diff --git a/.gitignore b/.gitignore index 9e95266ba7c00..aa61446f3f9f1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,11 @@ DerivedData .mailmap results +AAAAAAAA/ +build-dep-win/ +build-win/ +install-win/ + # Ignore Buildstream local files /Tools/buildstream/.bst2 /Tools/buildstream/cache diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt index 470bd20d4a3c5..b98c5fd07cd42 100644 --- a/Source/JavaScriptCore/CMakeLists.txt +++ b/Source/JavaScriptCore/CMakeLists.txt @@ -1552,7 +1552,12 @@ endif () if (CMAKE_COMPILER_IS_GNUCXX AND GCC_OFFLINEASM_SOURCE_MAP) message(STATUS "Enabling asm postprocessing") - set(LowLevelInterpreter_LAUNCHER "${RUBY_EXECUTABLE} ${JavaScriptCore_SCRIPTS_SOURCES_DIR}/postprocess-asm") + if (WIN32) + set(LowLevelInterpreter_LAUNCHER "${RUBY_EXECUTABLE} ${JavaScriptCore_SCRIPTS_SOURCES_DIR}/postprocess-asm-win") + else () + set(LowLevelInterpreter_LAUNCHER "${RUBY_EXECUTABLE} ${JavaScriptCore_SCRIPTS_SOURCES_DIR}/postprocess-asm") + endif () + get_target_property(PROP_RULE_LAUNCH_COMPILE LowLevelInterpreterLib RULE_LAUNCH_COMPILE) if (PROP_RULE_LAUNCH_COMPILE) set(LowLevelInterpreter_LAUNCHER "${LowLevelInterpreter_LAUNCHER} ${PROP_RULE_LAUNCH_COMPILE}") diff --git a/Source/JavaScriptCore/Scripts/postprocess-asm-win b/Source/JavaScriptCore/Scripts/postprocess-asm-win new file mode 100755 index 0000000000000..b0fda7ce862da --- /dev/null +++ b/Source/JavaScriptCore/Scripts/postprocess-asm-win @@ -0,0 +1,193 @@ +#!/usr/bin/env ruby + +# Copyright (C) 2020 Igalia S. L. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + +# Wrapper for a .cpp -> .o compilation command. It +# 1. converts the command to generate a `.s' file +# 2. runs the ASM postprocessor on it to generate the final `.s` file +# 3. assembles the `.s` file to a `.o` file + +$asm_suffix_pre = ".pre.s" +$asm_suffix = ".s" +$postprocessor = "#{File.dirname($0)}/resolve-asm-file-conflicts-win.rb" + + +$intermediate_paths = [] + +# We need to work with indices a lot and unfortunately 'getoptlong' in +# the standard library doesn't expose optind, so we're going with +# array searches for simplicity. +def index_nofail(ary, f, errmsg) + idx = ary.index { |el| + f.call(el) + } + if idx.nil? + $stderr.puts(errmsg) + exit(3) + end + idx +end + +# Find and return the source file for this compilation command, +# removing it from the args. Note that the path (A) as it appears here +# (coming from a cmake rule) is likely to be different to the +# anonymous argument (B) to the compilation command. However, A will +# be a suffix of B. +# +# Exit with an error if the argument is not there. This has already +# been checked by `cxx-wrapper`, otherwise we wouldn't be running. +def extract_input!(args) + prefix = '-DPOSTPROCESS_ASM=' + + idx = index_nofail(args, Proc.new { |arg| + arg.start_with?(prefix) + }, "No `-DPOSTPROCESS_ASM` argument`") + + path = args[idx][prefix.size..-1] + if path.size == 0 + $stderr.puts("Empty path in -DPOSTPROCESS_ASM=") + exit(3) + end + # We only need this to be defined for the preprocessor (not any + # wrapper) from now on. + args[idx] = "-DPOSTPROCESS_ASM" + path.gsub! '/', '\\\\' + return path +end + +# Get the index of the first argument ending in this suffix. +# +# Exit with an error if the argument isn't there. We're only ever +# called with arguments we know are being passed in by the build +# system. +def get_arg_idx_suffix(args, wanted) + index_nofail(args, Proc.new { |arg| + arg.end_with?(wanted) + }, "No argument ends with #{wanted}") +end + +# Get index of a given argument. Die if it's not there. +def get_arg_idx(args, wanted) + index_nofail(args, Proc.new { |arg| + arg == wanted + }, "No `#{wanted}` argument") +end + +# Get the index of `-o` and verify that an argument follows. +# Both are guaranteed to exist (from our build system). +def get_o_idx(args) + i = get_arg_idx(args, '-o') + if (i + 1) >= args.size + $stderr.puts("No argument to `-o`") + exit(3) + end + i +end + +# Run command and die if it fails, propagating the exit code. +def run_cmd(cmd) + pid = Process.spawn(*cmd) + Process.waitpid(pid) + ret = $? + if not ret.success? + $stderr.puts("Error running cmd: #{ret}") + exit(ret.exitstatus) + end +end + +# Convert +# cxx -o blah.o -c blah.cpp +# to +# cxx -o blah.s -S blah.cpp +def build_cxx_cmd(args) + c_idx = get_arg_idx(args, '-c') + o_idx = get_o_idx(args) + + cxx_args = args.clone + + cxx_args[c_idx] = '-S' + o_path = cxx_args[o_idx + 1] + cxx_args[o_idx + 1] = o_path.sub(/[.]obj$/, $asm_suffix) + $intermediate_paths << cxx_args[o_idx + 1] + if cxx_args[o_idx + 1] == o_path + $stderr.puts("Output file name not an object file: `#{o_path}`") + exit(3) + end + cxx_args +end + +# Do +# mv blah.S blah.pre.S +# The reason we do a rename instead of directly generating the .pre.s +# file when compiling is so that the corresponding .dwo file will have +# the correct name embedded. +def rename_s_file(args) + o_path = args[get_o_idx(args) + 1] + File.rename(o_path.sub(/[.]obj$/, $asm_suffix), + o_path.sub(/[.]obj$/, $asm_suffix_pre)) +end + +# Build +# postprocessor blah.pre.S blah.S +def build_postprocessor_cmd(args) + o_path = args[get_o_idx(args) + 1] + + pp_args = [ + "ruby", + $postprocessor, + o_path.sub(/[.]obj$/, $asm_suffix_pre), # input + o_path.sub(/[.]obj$/, $asm_suffix) # output + ] + $intermediate_paths << pp_args[-2] + $intermediate_paths << pp_args[-1] + pp_args +end + +# Build +# cxx -o blah.o -c blah.S +def build_as_cmd(args, i_path) + i_idx = get_arg_idx_suffix(args, i_path) + o_path = args[get_o_idx(args) + 1] + + as_args = args.clone + i_path = as_args[i_idx] + as_args[i_idx] = o_path.sub(/[.]obj$/, $asm_suffix) + as_args +end + +args = ARGV.to_a +i_path = extract_input!(args) + +begin + run_cmd(build_cxx_cmd(args)) + rename_s_file(args) + run_cmd(build_postprocessor_cmd(args)) + run_cmd(build_as_cmd(args, i_path)) +ensure + $intermediate_paths.each { |p| + if File.exist?(p) + File.delete(p) + end + } +end diff --git a/Source/JavaScriptCore/Scripts/resolve-asm-file-conflicts-win.rb b/Source/JavaScriptCore/Scripts/resolve-asm-file-conflicts-win.rb new file mode 100755 index 0000000000000..7a41ff0135c86 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/resolve-asm-file-conflicts-win.rb @@ -0,0 +1,456 @@ +#!/usr/bin/env ruby + +# Copyright (C) 2020 Igalia S. L. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + +# Resolve conflicts in `.file` directives in assembler files. Those +# may result from inline asm statements which themselves have `.file` +# directives. As the inline asm has no idea what the next free file +# number is, it'll generally have its own numbering. To get things to +# work we have to +# 1. remap conflicting file numbers +# 2. change `.loc` directives to reference the appropriate file number. +# +# To be able to do that, we need some concept of "scope", i.e. which +# set of files a given `.loc` directive refers to. We get that by +# tracking the #APP/#NOAPP directives that the compiler emits when it +# switch to/from inline asm. +# +# In effect, we convert +# .file 1 "foo" +# #APP +# .file 1 "bar" +# .file 2 "foo" +# .loc 1, X +# #NOAPP +# .loc 1, Y +# to +# .file 1 "foo" +# #APP +# .file 2 "bar" +# .file 1 "foo" +# .loc 2, X +# #NOAPP +# .loc 1, Y + +require 'pathname' +require 'stringio' +require 'strscan' + +ParseResultSuccess = Struct.new(:str) +ParseResultError = Struct.new(:error) + +# Parses whatever follows a .file assembler directive +class FileDirectiveArgScanner + def initialize(s) + @s = StringScanner.new(s) + end + def parse + @s.skip(/\s*/) + + # We require at least one string literal + ret1 = parse_string_literal + if ret1.respond_to?(:error) + return ret1 + end + + @s.skip(/\s*/) + if @s.eos? + #This on windows MINGW makes tests fail and compilation stop. Remove "cleanpath" for now. + #return ParseResultSuccess.new(Pathname.new(ret1.str).cleanpath.to_s) + return ParseResultSuccess.new(Pathname.new(ret1.str).to_s) + end + # If anything follows, it needs to be a string literal + ret2 = parse_string_literal + if ret2.respond_to?(:error) + return ret2 + end + @s.skip(/\s*/) + if not @s.eos? + md5 = parse_md5 + if md5.respond_to?(:error) + return ParseResultError.new("Expected end of line or md5, not `#{@s.rest}`") + end + end + @s.skip(/\s*/) + if not @s.eos? + return ParseResultError.new("Expected end of line, not `#{@s.rest}`") + end + filepath = Pathname.new(ret2.str) + if not filepath.absolute? + filepath = Pathname.new(ret1.str) / ret2.str + end + #This on windows MINGW makes tests fail and compilation stop. Remove "cleanpath" for now. + #return ParseResultSuccess.new(filepath.cleanpath.to_s) + return ParseResultSuccess.new(filepath.to_s) + end + def parse_string_literal + if @s.scan(/"/).nil? + err = "Expected string literal at `#{@s.string}` (pos #{@s.pos})" + return ParseResultError.new(err) + end + parse_until_end_of_string_literal + end + def parse_until_end_of_string_literal + start_pos = @s.pos + while true + # Search for our special characters + @s.skip(/[^"\\]+/) + if @s.scan(/\\/) + if @s.scan(/\\/) + # When we see '\\', consume both characters so that the + # second '\' will not be treated as an escape char. + next + elsif @s.scan(/"/) + # For '\"', consume both characters so that the '"' will not + # terminate the string. + next + end + next + elsif @s.scan(/"/) + # '"' without a preceeding '\'; terminate the literal. + # We're already past the '"', so the literal ends at -2 + # characters. + return ParseResultSuccess.new(@s.string[start_pos..(@s.pos - 2)]) + elsif @s.eos? + err = "Unterminated string literal (starting at pos #{start_pos} in #{@s.string}" + return ParseResultError.new(err) + end + raise "Internal error (#{@s.inspect})" + end + end + def parse_md5 + md5 = @s.scan(/md5\s+(0x)?\h+/) + if md5.nil? + ParseResultError.new("Could not parse md5 at pos #{@s.pos} in #{@s.string}") + else + ParseResultSuccess.new(md5) + end + end +end + +def test(outf, str, res) + pr = FileDirectiveArgScanner.new(str).parse + if res.is_a?(Array) + if pr.respond_to?(:error) + outf.puts("Parse result is `#{pr.error}` but expected #{res}") + return false + end + if pr.str != res[0] + outf.puts("Parsed path `#{pr.str}` but expected `#{res[0]}`") + return false + end + return true + elsif res.is_a?(String) + if pr.respond_to?(:error) + if not pr.error.downcase.include?(res.downcase) + err = "Error message `#{pr.error}` does not include expected substring `#{res}`" + outf.puts(err) + return false + end + return true + end + outf.puts("Expected error (#{res}) but got successful parse #{pr.str}") + return false + else + raise "Internal error #{res.class}" + end +end + +def selftest + nr_succeeded = 0 + tests = [ + # simple string + ['"foo/bar"', ["foo/bar"]], + + ['"foo', "Unterminated string literal"], + + ['"foo\"', "Unterminated string literal"], + + # "foo\" + ["\"foo\\\"", "Unterminated string literal"], + + # "foo\\" + ["\"foo\\\\\"", ["foo\x5c\x5c"]], + + # Can escape '"' + ['"foo\"bar"', ['foo\"bar']], + + # Can parse relative + ['"foo/bar"', ['foo/bar']], + + # Can parse absolute + ['"/bar"', ['/bar']], + + # Can parse absolute with two components + ['"/bar/baz"', ['/bar/baz']], + + # Can detect stray token + ['"foo" bar', "Expected string literal"], + + # Can detect stray token without whitespace + ['"foo"bar', "Expected string literal"], + + # Can parse two string literals + ['"working_directory" "path"', ['working_directory/path']], + + # Will not concatenate the working directory to an absolute path + ['"working_directory" "/path"', ['/path']], + + # Will only accept up to 2 string literals + ['"first" "second" "third"', "Expected end of line"], + + # Can detect stray token after 2nd string literal + ['"foo" "bar" baz', "Expected end of line"], + + # Can detect stray token after 2nd string literal without whitespace + ['"foo" "bar"baz', "Expected end of line"], + + # Can detect unterminated 3rd string literal + ['"foo" "bar" "baz', "Expected end of line"], + + # Can parse md5 + ['"foo" "bar" md5 0xabcde0123456789', ['foo/bar']], + + # Can parse md5 without 0x prefix + ['"foo" "bar" md5 abcde0123456789', ['foo/bar']] + + ] + outf = StringIO.new("") + tests.each { |str, res| + if test(outf, str, res) + nr_succeeded += 1 + end + } + if nr_succeeded != tests.size + $stderr.puts(outf.string) + $stderr.puts("Some self tests failed #{nr_succeeded}/#{tests.size}") + exit(3) + end +end + +# Keep track of which fileno is assigned to which file path. We call +# the fileno a 'slot'. +class FileSlotTracker + @@next_free = 1 # Next free global slot + @@paths = {} # Maps path -> global slot + def initialize(parent) + @parent = parent + # This maps from our own local slots (i.e. within an APP section) + # to a global slot. + @slot_map = {} + end + # We make sure that .file directives that specify the same path are + # dedup'd, i.e. if we see + # .file N "/path/to/include.h" + # ... + # .file M "/path/to/include.h" + # then the "local" N, M slots will be mapped to the same "global" slot. + def register_path(path, slot) + curr_slot = @@paths[path] + if curr_slot.nil? + # We haven't seen this file before + if slot <= @@next_free + # Desired file slot either clashes with an existing one, or is + # the next one to be allocated. In either case, assign the + # next free slot. + assign_next_slot(path) + else + # Don't allow slot gaps. Technically we could handle them, but + # they should never happen; bail now rather than papering over + # an earlier error. + $stderr.puts("File wants slot #{slot} but only seen #{@@next_free} so far") + exit(2) + end + else + # We've already assigned a slot for this file. + end + @slot_map[slot] = @@paths[path] + if @slot_map[slot].nil? + raise "Didn't map local slot #{slot}" + end + end + # Return global slot for path + def slot_for_path(path) + return @@paths[path] + end + # Return global slot that will replace the local slot + def remap_slot(slot) + ret = nil + if @slot_map.size > 0 + # If the current NO_APP segment has defined a .file, only look + # in the current FileSlotTracker. This is the case for a + # top-level inline asm statement. + ret = @slot_map[slot] + elsif not @parent.nil? + # If the current NO_APP segment has not defined a .file, clearly + # all .loc directives refer to files defined in the APP + # part. This is the case for non-top-level inline asm + # statements. + ret = @parent.remap_slot(slot) + end + if ret.nil? + raise "No global slot for #{slot}" + end + ret + end + private + def assign_next_slot(path) + @@paths[path] = @@next_free + @@next_free += 1 + end +end + +# Return sequential lines, while keeping track of whether we're in an +# #APP or #NOAPP section. +class AsmReader + attr_reader :in_app + attr_accessor :app_to_noapp, :noapp_to_app + def initialize(f) + @f = f + @f.rewind + @linenr = 0 + @in_app = false + @last_switch = "start of file" # For error messages + end + def next_line + while true + l = @f.gets + if l.nil? + return l + end + @linenr += 1 + if /^#\s*APP\s*/.match(l) + if @in_app + raise "#APP on line #{@linenr} but already in #APP (#{@last_switch})" + end + @in_app = true + @last_switch = @linenr + if @noapp_to_app + @noapp_to_app.call() + end + end + if /^#\s*NO_APP\s*/.match(l) + if not @in_app + raise "#NOAPP on line #{@linenr} but was not in #APP (last swich at #{@last_switch})" + end + @in_app = false + @last_switch = @linenr + if @app_to_noapp + @app_to_noapp.call() + end + end + return l + end + end +end + +class FileConflictResolver + @@file_re = /^\s*[.]file\s+(?\d+)\s+(?.*)$/ + @@loc_re = /^(?\s*)[.]loc(?\s+)(?\d+)(?\s+\d+.*)$/ + def initialize(inf, outf) + @outf = outf + @trackers = [FileSlotTracker.new(nil)] + @asm_reader = AsmReader.new(inf) + # When we enter an #APP section (i.e. asm emitted from an expanded + # inline asm statement), create a new file tracker, in effect + # processing the .file and .loc directives in a new "namespace" + # (as far as the file numbers are concerned). This is an array, + # but in practice the size will either be 1 (NOAPP) or 2 (APP). + @asm_reader.app_to_noapp = Proc.new { || + @trackers.pop + } + @asm_reader.noapp_to_app = Proc.new { || + @trackers.push(FileSlotTracker.new(@trackers[-1])) + } + end + def run + while true + l = @asm_reader.next_line + break unless l + + md = @@file_re.match(l) + if md + file_directive(md) + next + end + md = @@loc_re.match(l) + if md + loc_directive(md) + next + end + @outf.write(l) + next + end + end + def loc_directive(md) + tracker = @trackers.last + slot = tracker.remap_slot(md[:slot].to_i) + @outf.puts("#{md[:white1]}.loc#{md[:white2]}#{slot}#{md[:rest]}") + end + def file_directive(md) + slot = md[:slot].to_i + tracker = @trackers.last + + pr = FileDirectiveArgScanner.new(md[:rest]).parse + if pr.respond_to?(:error) + $stderr.puts("Error parsing path argument to .file directive: #{pr.error}") + exit(2) + end + + path = pr.str + + if slot != 0 + tracker.register_path(path, slot) + slot = tracker.slot_for_path(path) + end + @outf.puts("\t.file\t#{slot} #{md[:rest]}") + end +end + +# First, make sure our tests still pass. This only takes a fraction of +# our runtime and ensures the tests will get run by anyone trying out +# changes to this file. +selftest + +if ARGV.size != 2 + $stderr.puts("Usage: #{$0} input output") + exit(2) +end + +inpath, outpath = ARGV.collect { |n| Pathname.new(n) } + +if not inpath.file? + $stderr.puts("Not a regular file: `#{inpath}`") + exit(2) +end + +if inpath.extname.upcase != ".S" + $stderr.puts("warning: file `#{inpath}` doesn't have a `.s` or `.S` extension. Going on anyway...") +end + +File.open(inpath, "r") { |inf| + File.open(outpath, "w") { |outf| + FileConflictResolver.new(inf, outf).run + } +} diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp index ab517ec48b083..90488ffd01cbd 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp +++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp @@ -370,7 +370,9 @@ asm ( "popl %ecx" "\n" "popl %ebp" "\n" "ret" "\n" +#if !OS(WINDOWS) ".previous" "\n" +#endif ); #endif @@ -739,7 +741,9 @@ asm ( "popq %rcx" "\n" "popq %rbp" "\n" "ret" "\n" +#if !OS(WINDOWS) ".previous" "\n" +#endif ); // And now, the slower version that saves the full width of vectors in xmm registers. @@ -937,7 +941,9 @@ asm ( "popq %rcx" "\n" "popq %rbp" "\n" "ret" "\n" +#if !OS(WINDOWS) ".previous" "\n" +#endif ); #endif // COMPILER(GCC_COMPATIBLE) #endif // CPU(X86_64) diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h index 248af2a46d88f..108c33a019365 100644 --- a/Source/JavaScriptCore/jit/JIT.h +++ b/Source/JavaScriptCore/jit/JIT.h @@ -726,13 +726,13 @@ namespace JSC { } #if OS(WINDOWS) && CPU(X86_64) - template + template struct is64BitType { static constexpr bool value = sizeof(Type) <= 8; }; - template<> - struct is64BitType { + template + struct is64BitType { static constexpr bool value = true; }; diff --git a/Source/JavaScriptCore/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp index 81f426f302d91..ff78fe02d9dde 100644 --- a/Source/JavaScriptCore/llint/LLIntData.cpp +++ b/Source/JavaScriptCore/llint/LLIntData.cpp @@ -103,15 +103,16 @@ void initialize() #else // !ENABLE(C_LOOP) if (UNLIKELY(g_jscConfig.vmEntryDisallowed)) + { neuterOpcodeMaps(); - else { + } + else + { llint_entry(&g_opcodeMap, &g_opcodeMapWide16, &g_opcodeMapWide32); - #if ENABLE(WEBASSEMBLY) wasm_entry(&g_opcodeMap[numOpcodeIDs], &g_opcodeMapWide16[numOpcodeIDs], &g_opcodeMapWide32[numOpcodeIDs]); #endif // ENABLE(WEBASSEMBLY) } - static_assert(llint_throw_from_slow_path_trampoline < UINT8_MAX); static_assert(wasm_throw_from_slow_path_trampoline < UINT8_MAX); for (unsigned i = 0; i < maxBytecodeStructLength + 1; ++i) { diff --git a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h index ad7273a2d3dde..f3146cf61f294 100644 --- a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h +++ b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h @@ -55,13 +55,13 @@ #define OFFLINE_ASM_C_LOOP 0 #define OFFLINE_ASM_C_LOOP_WIN 0 -#if CPU(X86) && !COMPILER(MSVC) +#if CPU(X86) && !OS(WINDOWS) #define OFFLINE_ASM_X86 1 #else #define OFFLINE_ASM_X86 0 #endif -#if CPU(X86) && COMPILER(MSVC) +#if CPU(X86) && OS(WINDOWS) #define OFFLINE_ASM_X86_WIN 1 #else #define OFFLINE_ASM_X86_WIN 0 @@ -85,13 +85,13 @@ #define OFFLINE_ASM_ARMv7 0 #endif -#if CPU(X86_64) && !COMPILER(MSVC) +#if CPU(X86_64) && !OS(WINDOWS) #define OFFLINE_ASM_X86_64 1 #else #define OFFLINE_ASM_X86_64 0 #endif -#if CPU(X86_64) && COMPILER(MSVC) +#if CPU(X86_64) && OS(WINDOWS) #define OFFLINE_ASM_X86_64_WIN 1 #else #define OFFLINE_ASM_X86_64_WIN 0 diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb index 757330b73eacb..6afeb916ba1f3 100644 --- a/Source/JavaScriptCore/offlineasm/x86.rb +++ b/Source/JavaScriptCore/offlineasm/x86.rb @@ -548,7 +548,11 @@ def x86LoadOperand(kind, dst) # https://bugs.webkit.org/show_bug.cgi?id=175104 used if !isIntelSyntax - $asm.puts "movq #{asmLabel}@GOTPCREL(%rip), #{dst.x86Operand(:ptr)}" + if isWin + $asm.puts "leaq #{asmLabel}(%rip), #{dst.x86Operand(:ptr)}" + else + $asm.puts "movq #{asmLabel}@GOTPCREL(%rip), #{dst.x86Operand(:ptr)}" + end else $asm.puts "lea #{dst.x86Operand(:ptr)}, #{asmLabel}" end @@ -677,7 +681,11 @@ def emitX86Lea(src, dst, kind) if src.is_a? LabelReference src.used if !isIntelSyntax - $asm.puts "movq #{src.asmLabel}@GOTPCREL(%rip), #{dst.x86Operand(:ptr)}" + if isWin + $asm.puts "leaq #{src.asmLabel}(%rip), #{dst.x86Operand(:ptr)}" + else + $asm.puts "movq #{src.asmLabel}@GOTPCREL(%rip), #{dst.x86Operand(:ptr)}" + end else $asm.puts "lea #{dst.x86Operand(:ptr)}, #{src.asmLabel}" end diff --git a/Source/JavaScriptCore/runtime/MathCommon.cpp b/Source/JavaScriptCore/runtime/MathCommon.cpp index 0177baa883473..d4b12afd20bb6 100644 --- a/Source/JavaScriptCore/runtime/MathCommon.cpp +++ b/Source/JavaScriptCore/runtime/MathCommon.cpp @@ -564,11 +564,19 @@ JSC_DEFINE_JIT_OPERATION(sqrtFloat, float, (float value)) JSC_DEFINE_JIT_OPERATION(stdPowDouble, double, (double x, double y)) { +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return pow(x, y); +#else return std::pow(x, y); +#endif } JSC_DEFINE_JIT_OPERATION(stdPowFloat, float, (float x, float y)) { +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return pow(x, y); +#else return std::pow(x, y); +#endif } JSC_DEFINE_JIT_OPERATION(fmodDouble, double, (double x, double y)) diff --git a/Source/WTF/wtf/PlatformQt.cmake b/Source/WTF/wtf/PlatformQt.cmake index fb18c3b390084..a03f41c3f235c 100644 --- a/Source/WTF/wtf/PlatformQt.cmake +++ b/Source/WTF/wtf/PlatformQt.cmake @@ -16,6 +16,7 @@ QTWEBKIT_GENERATE_MOC_FILES_CPP(WTF qt/MainThreadQt.cpp qt/RunLoopQt.cpp) if (WIN32) list(APPEND WTF_PUBLIC_HEADERS text/win/WCharStringEXtras.h + win/DbgHelperWin.h ) list(APPEND WTF_SOURCES text/win/StringWin.cpp @@ -24,7 +25,10 @@ if (WIN32) win/FileSystemWin.cpp win/OSAllocatorWin.cpp win/PathWalker.cpp - win/ThreadSpecificWin.cpp + + #missing file, removing it for now. + #win/ThreadSpecificWin.cpp + win/ThreadingWin.cpp ) list(APPEND WTF_LIBRARIES @@ -78,7 +82,6 @@ endif () if (USE_UNIX_DOMAIN_SOCKETS) list(APPEND WTF_SOURCES qt/WorkQueueQt.cpp - unix/UniStdExtrasUnix.cpp ) QTWEBKIT_GENERATE_MOC_FILES_CPP(WTF qt/WorkQueueQt.cpp) @@ -111,8 +114,12 @@ endif () if (WIN32) list(APPEND WTF_SOURCES win/CPUTimeWin.cpp - win/WorkQueueWin.cpp + win/SignalsWin.cpp + + qt/WorkQueueQt.cpp ) + QTWEBKIT_GENERATE_MOC_FILES_CPP(WTF qt/WorkQueueQt.cpp) + list(APPEND WTF_LIBRARIES winmm ) @@ -156,6 +163,7 @@ if (WIN32) list(APPEND WTF_SOURCES win/MemoryFootprintWin.cpp win/MemoryPressureHandlerWin.cpp + win/Win32Handle.cpp ) list(APPEND WTF_PUBLIC_HEADERS win/Win32Handle.h diff --git a/Source/WTF/wtf/PlatformUse.h b/Source/WTF/wtf/PlatformUse.h index 8c6bdebe4c4b5..0b2b8ae482af4 100644 --- a/Source/WTF/wtf/PlatformUse.h +++ b/Source/WTF/wtf/PlatformUse.h @@ -44,7 +44,7 @@ /* Export macro support. Detects the attributes available for shared library symbol export decorations. */ -#if OS(WINDOWS) || (COMPILER_HAS_CLANG_DECLSPEC(dllimport) && COMPILER_HAS_CLANG_DECLSPEC(dllexport)) +#if (COMPILER_HAS_CLANG_DECLSPEC(dllimport) && COMPILER_HAS_CLANG_DECLSPEC(dllexport)) #define USE_DECLSPEC_ATTRIBUTE 1 #elif defined(__GNUC__) #define USE_VISIBILITY_ATTRIBUTE 1 diff --git a/Source/WTF/wtf/Threading.cpp b/Source/WTF/wtf/Threading.cpp index 054353f5794ca..792648fb27b4e 100644 --- a/Source/WTF/wtf/Threading.cpp +++ b/Source/WTF/wtf/Threading.cpp @@ -506,7 +506,7 @@ void initialize() #if PLATFORM(COCOA) initializeLibraryPathDiagnostics(); #endif -#if OS(WINDOWS) +#if OS(WINDOWS) && !PLATFORM(QT) RunLoop::registerRunLoopMessageWindowClass(); #endif }); diff --git a/Source/WTF/wtf/WorkQueue.h b/Source/WTF/wtf/WorkQueue.h index f561d40e069a6..1ab806a8d3882 100644 --- a/Source/WTF/wtf/WorkQueue.h +++ b/Source/WTF/wtf/WorkQueue.h @@ -35,13 +35,13 @@ #if USE(COCOA_EVENT_LOOP) || (PLATFORM(QT) && USE(MACH_PORTS)) #include #include -#elif PLATFORM(QT) && USE(UNIX_DOMAIN_SOCKETS) +#elif PLATFORM(QT)// && USE(UNIX_DOMAIN_SOCKETS) #include #else #include #endif -#if PLATFORM(QT) && USE(UNIX_DOMAIN_SOCKETS) +#if PLATFORM(QT)// && USE(UNIX_DOMAIN_SOCKETS) QT_BEGIN_NAMESPACE class QProcess; QT_END_NAMESPACE @@ -62,7 +62,7 @@ class WorkQueueBase : public ThreadSafeRefCounted, protected Thre #if USE(COCOA_EVENT_LOOP) dispatch_queue_t dispatchQueue() const { return m_dispatchQueue.get(); } -#elif PLATFORM(QT) && USE(UNIX_DOMAIN_SOCKETS) +#elif PLATFORM(QT)// && USE(UNIX_DOMAIN_SOCKETS) QSocketNotifier* registerSocketEventHandler(int, QSocketNotifier::Type, WTF::Function&&); void dispatchOnTermination(QProcess*, WTF::Function&&); #endif @@ -75,13 +75,15 @@ class WorkQueueBase : public ThreadSafeRefCounted, protected Thre WorkQueueBase(const char* name, Type, QOS); #if USE(COCOA_EVENT_LOOP) || (PLATFORM(QT) && USE(MACH_PORTS)) explicit WorkQueueBase(OSObjectPtr&&); -#elif !PLATFORM(QT) +#elif PLATFORM(QT)// && USE(UNIX_DOMAIN_SOCKETS) + //Nothing here... +#else explicit WorkQueueBase(RunLoop&); #endif #if USE(COCOA_EVENT_LOOP) || (PLATFORM(QT) && USE(MACH_PORTS)) OSObjectPtr m_dispatchQueue; -#elif PLATFORM(QT) && USE(UNIX_DOMAIN_SOCKETS) +#elif PLATFORM(QT)// && USE(UNIX_DOMAIN_SOCKETS) class WorkItemQt; QThread* m_workThread; friend class WorkItemQt; @@ -110,7 +112,7 @@ class WTF_CAPABILITY("is current") WTF_EXPORT_PRIVATE WorkQueue : public WorkQue void ref() const override; void deref() const override; -#if PLATFORM(QT) && USE(UNIX_DOMAIN_SOCKETS) +#if PLATFORM(QT)// && USE(UNIX_DOMAIN_SOCKETS) class WorkItemQt; QThread* m_workThread; friend class WorkItemQt; diff --git a/Source/WTF/wtf/qt/RunLoopQt.cpp b/Source/WTF/wtf/qt/RunLoopQt.cpp index 6de0c5d322d83..79a04b3b9c1f7 100644 --- a/Source/WTF/wtf/qt/RunLoopQt.cpp +++ b/Source/WTF/wtf/qt/RunLoopQt.cpp @@ -113,15 +113,23 @@ class RunLoop::TimerObject : public QObject { }; static QEventLoop* currentEventLoop; +static bool mainEventLoopIsRunning = false; void RunLoop::run() { - static bool mainEventLoopIsRunning = false; - if (!mainEventLoopIsRunning) { + /* + This call to QCoreApplication::exec() must be protected to not accidentially be called from another thread. + bacause it will lock (freeze) WebKit if it happens. + */ + + if (!mainEventLoopIsRunning && WTF::isMainThread()) + { mainEventLoopIsRunning = true; QCoreApplication::exec(); mainEventLoopIsRunning = false; - } else { + } + else + { QEventLoop eventLoop; QEventLoop* previousEventLoop = currentEventLoop; currentEventLoop = &eventLoop; @@ -135,9 +143,22 @@ void RunLoop::run() void RunLoop::stop() { if (currentEventLoop) + { currentEventLoop->exit(); - else + } + else if(mainEventLoopIsRunning) + { QCoreApplication::exit(); + } + else + { + /* + Do nothing?, there is no more QEvenLoops and mainEventLoop was not started + Not sure if all this is right, so leaving it as it is + Maybe someone with more knowledge will chime in here later to fix this mess. + */ + return; + } } RunLoop::RunLoop() diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp index 269465684d4b5..fc5c00b531a54 100644 --- a/Source/WebCore/dom/Node.cpp +++ b/Source/WebCore/dom/Node.cpp @@ -2511,7 +2511,7 @@ void Node::dispatchDOMActivateEvent(Event& underlyingClickEvent) #if ENABLE(QT_GESTURE_EVENTS) bool Node::dispatchGestureEvent(const PlatformGestureEvent& event) { - RefPtr gestureEvent = GestureEvent::create(document().defaultView(), event); + RefPtr gestureEvent = GestureEvent::create(document().windowProxy(), event); if (!gestureEvent.get()) return false; @@ -2520,7 +2520,7 @@ bool Node::dispatchGestureEvent(const PlatformGestureEvent& event) if (downcast(*this).isDisabledFormControl()) return false; - EventDispatcher::dispatchEvent(this, *gestureEvent); + EventDispatcher::dispatchEvent(*this, *gestureEvent); ASSERT(!gestureEvent->defaultPrevented()); return gestureEvent->defaultHandled() || gestureEvent->defaultPrevented(); diff --git a/Source/WebCore/dom/qt/GestureEvent.cpp b/Source/WebCore/dom/qt/GestureEvent.cpp index 3564bcd716032..4a98b3b6cf05f 100644 --- a/Source/WebCore/dom/qt/GestureEvent.cpp +++ b/Source/WebCore/dom/qt/GestureEvent.cpp @@ -38,13 +38,13 @@ RefPtr GestureEvent::create(AbstractView* view, const PlatformGest { AtomString eventType; switch (event.type()) { - case PlatformEvent::GestureTap: + case PlatformEventType::GestureTap: eventType = eventNames().gesturetapEvent; break; - case PlatformEvent::GestureLongPress: + case PlatformEventType::GestureLongPress: default: - return 0; + return nullptr; } - return adoptRef(new GestureEvent(eventType, MonotonicTime(event.timestamp()), view, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(), event.modifierKeys())); + return adoptRef(new GestureEvent(eventType, event.timestamp().approximateMonotonicTime(), view, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(), event.modifiers())); } EventInterface GestureEvent::eventInterface() const @@ -54,11 +54,7 @@ EventInterface GestureEvent::eventInterface() const } GestureEvent::GestureEvent(const AtomString& type, MonotonicTime timestamp, AbstractView* view, int screenX, int screenY, int clientX, int clientY, OptionSet modifiers) - : MouseRelatedEvent(type, CanBubble::Yes, IsCancelable::Yes, IsComposed::Yes, timestamp, view, 0, IntPoint(screenX, screenY), IntPoint(clientX, clientY) -#if ENABLE(POINTER_LOCK) - , IntPoint(0, 0) -#endif - , modifierKeys) + : MouseRelatedEvent(type, CanBubble::Yes, IsCancelable::Yes, IsComposed::Yes, timestamp, view, 0, IntPoint(screenX, screenY), IntPoint(clientX, clientY), 0, 0, modifiers) { } diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp index 6d09a04e355f8..825c7620d11c7 100644 --- a/Source/WebCore/page/EventHandler.cpp +++ b/Source/WebCore/page/EventHandler.cpp @@ -3433,20 +3433,20 @@ bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent) Scrollbar* scrollbar = 0; IntPoint adjustedPoint = gestureEvent.position(); - HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent; + HitTestRequest::Type hitType = HitTestRequest::Type::TouchEvent; if (gestureEvent.type() == PlatformEvent::Type::GestureTap) { // The mouseup event synthesized for this gesture will clear the active state of the // targeted node, so performing a ReadOnly hit test here is fine. - hitType |= HitTestRequest::ReadOnly; + hitType |= HitTestRequest::Type::ReadOnly; } else - hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly; + hitType |= HitTestRequest::Type::Active | HitTestRequest::Type::ReadOnly; if (!shouldGesturesTriggerActive()) - hitType |= HitTestRequest::ReadOnly; + hitType |= HitTestRequest::Type::ReadOnly; - if ((!scrollbar && !eventTarget) || !(hitType & HitTestRequest::ReadOnly)) { - IntPoint hitTestPoint = m_frame.view()->windowToContents(adjustedPoint); - HitTestResult result = hitTestResultAtPoint(hitTestPoint, hitType | HitTestRequest::AllowFrameScrollbars); + if ((!scrollbar && !eventTarget) || !static_cast(hitType & HitTestRequest::Type::ReadOnly)) { + IntPoint hitTestPoint = m_frame->view()->windowToContents(adjustedPoint); + HitTestResult result = hitTestResultAtPoint(hitTestPoint, hitType | HitTestRequest::Type::AllowFrameScrollbars); eventTarget = result.targetNode(); if (!scrollbar) scrollbar = result.scrollbar(); @@ -3466,7 +3466,7 @@ bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent) // FIXME: A more general scroll system (https://bugs.webkit.org/show_bug.cgi?id=80596) will // eliminate the need for this. - TemporaryChange baseEventType(m_baseEventType, gestureEvent.type()); + //TemporaryChange baseEventType(m_baseEventType, gestureEvent.type()); switch (gestureEvent.type()) { case PlatformEvent::Type::GestureTap: @@ -3489,22 +3489,22 @@ bool EventHandler::handleGestureTap(const PlatformGestureEvent& gestureEvent) #endif PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition(), - NoButton, PlatformEvent::Type::MouseMoved, /* clickCount */ 0, - gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp(), ForceAtClick); + MouseButton::None, PlatformEvent::Type::MouseMoved, /* clickCount */ 0, + gestureEvent.modifiers(), gestureEvent.timestamp(), ForceAtClick, SyntheticClickType::NoTap); mouseMoved(fakeMouseMove); int tapCount = 1; bool defaultPrevented = false; PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition(), - LeftButton, PlatformEvent::MousePressed, tapCount, - gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp(), ForceAtClick); - defaultPrevented |= handleMousePressEvent(fakeMouseDown); + MouseButton::Left, PlatformEventType::MousePressed, tapCount, + gestureEvent.modifiers(), gestureEvent.timestamp(), ForceAtClick, SyntheticClickType::NoTap); + defaultPrevented |= handleMousePressEvent(fakeMouseDown).wasHandled(); PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(), - LeftButton, PlatformEvent::MouseReleased, tapCount, - gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp(), ForceAtClick); - defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp); + MouseButton::Left, PlatformEventType::MouseReleased, tapCount, + gestureEvent.modifiers(), gestureEvent.timestamp(), ForceAtClick, SyntheticClickType::NoTap); + defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp).wasHandled(); return defaultPrevented; } @@ -3709,16 +3709,16 @@ bool EventHandler::sendContextMenuEventForKey() bool EventHandler::sendContextMenuEventForGesture(const PlatformGestureEvent& event) { #if OS(WINDOWS) - PlatformEvent::Type eventType = PlatformEvent::MouseReleased; + PlatformEvent::Type eventType = PlatformEvent::Type::MouseReleased; #else - PlatformEvent::Type eventType = PlatformEvent::MousePressed; + PlatformEvent::Type eventType = PlatformEvent::Type::MousePressed; #endif IntPoint adjustedPoint = event.position(); #if ENABLE(TOUCH_ADJUSTMENT) adjustGesturePosition(event, adjustedPoint); #endif - PlatformMouseEvent mouseEvent(adjustedPoint, event.globalPosition(), RightButton, eventType, 1, false, false, false, false, WTF::currentTime(), ForceAtClick); + PlatformMouseEvent mouseEvent(adjustedPoint, event.globalPosition(), MouseButton::Right, eventType, 1, { }, WallTime::now(), ForceAtClick, SyntheticClickType::NoTap); // To simulate right-click behavior, we send a right mouse down and then // context menu event. handleMousePressEvent(mouseEvent); diff --git a/Source/WebCore/platform/PlatformScreen.h b/Source/WebCore/platform/PlatformScreen.h index efa9c30953573..2df8e61bf4c6b 100644 --- a/Source/WebCore/platform/PlatformScreen.h +++ b/Source/WebCore/platform/PlatformScreen.h @@ -150,7 +150,7 @@ WEBCORE_EXPORT float screenScaleFactor(UIScreen * = nullptr); #endif #if ENABLE(TOUCH_EVENTS) -#if PLATFORM(GTK) || PLATFORM(WPE) +#if PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(QT) WEBCORE_EXPORT bool screenHasTouchDevice(); WEBCORE_EXPORT bool screenIsTouchPrimaryInputDevice(); #else diff --git a/Source/WebCore/platform/ScrollAnimator.cpp b/Source/WebCore/platform/ScrollAnimator.cpp index a0e8bba18ff78..cd21c8d9b2a4a 100644 --- a/Source/WebCore/platform/ScrollAnimator.cpp +++ b/Source/WebCore/platform/ScrollAnimator.cpp @@ -399,6 +399,14 @@ bool ScrollAnimator::scrollAnimationEnabled() const { return m_scrollableArea.scrollAnimatorEnabled(); } +#elif PLATFORM(QT) +bool ScrollAnimator::scrollAnimationEnabled() const +{ + // FIXME: + // Scrolling animation doesn't work right now. + // Return false so that non-animated wheel scrolling works. + return false; +} #endif void ScrollAnimator::cancelAnimations() diff --git a/Source/WebCore/platform/ScrollAnimator.h b/Source/WebCore/platform/ScrollAnimator.h index 3aba2efe74d79..ac934eabedfa6 100644 --- a/Source/WebCore/platform/ScrollAnimator.h +++ b/Source/WebCore/platform/ScrollAnimator.h @@ -163,7 +163,7 @@ class ScrollAnimator : private ScrollingEffectsControllerClient { void deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) const final; void removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier, WheelEventTestMonitor::DeferReason) const final; -#if PLATFORM(GTK) || USE(NICOSIA) +#if PLATFORM(GTK) || PLATFORM(QT) || USE(NICOSIA) bool scrollAnimationEnabled() const final; #endif diff --git a/Source/WebCore/platform/Scrollbar.cpp b/Source/WebCore/platform/Scrollbar.cpp index bf5682896c7f6..8b0dad4234491 100644 --- a/Source/WebCore/platform/Scrollbar.cpp +++ b/Source/WebCore/platform/Scrollbar.cpp @@ -346,7 +346,7 @@ bool Scrollbar::gestureEvent(const PlatformGestureEvent& evt) { bool handled = false; switch (evt.type()) { - case PlatformEvent::GestureTap: + case PlatformEventType::GestureTap: if (m_pressedPart != ThumbPart && m_pressedPart != NoPart) handled = m_scrollableArea.scroll(pressedPartScrollDirection(), pressedPartScrollGranularity()); break; diff --git a/Source/WebCore/platform/ScrollingMomentumCalculator.cpp b/Source/WebCore/platform/ScrollingMomentumCalculator.cpp index 84abfcc3f02ce..cf1e8f172540c 100644 --- a/Source/WebCore/platform/ScrollingMomentumCalculator.cpp +++ b/Source/WebCore/platform/ScrollingMomentumCalculator.cpp @@ -98,7 +98,11 @@ FloatPoint BasicScrollingMomentumCalculator::cubicallyInterpolatedOffsetAtProgre ASSERT(!m_forceLinearAnimationCurve); FloatPoint interpolatedPoint; for (int i = 0; i < 4; ++i) +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + interpolatedPoint += pow(progress, i) * m_snapAnimationCurveCoefficients[i]; +#else interpolatedPoint += std::pow(progress, i) * m_snapAnimationCurveCoefficients[i]; +#endif return interpolatedPoint; } @@ -221,7 +225,11 @@ void BasicScrollingMomentumCalculator::initializeSnapProgressCurve() m_snapAnimationCurveMagnitude = initialScrollSnapCurveMagnitude; for (int i = 0; i < maxNumScrollSnapParameterEstimationIterations; ++i) { m_snapAnimationDecayFactor = m_snapAnimationCurveMagnitude / (m_snapAnimationCurveMagnitude - initialProgress); +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + m_snapAnimationCurveMagnitude = 1.0f / (1.0f - pow(m_snapAnimationDecayFactor, -framesPerSecond * scrollSnapAnimationDuration.value())); +#else m_snapAnimationCurveMagnitude = 1.0f / (1.0f - std::pow(m_snapAnimationDecayFactor, -framesPerSecond * scrollSnapAnimationDuration.value())); +#endif if (std::abs(m_snapAnimationDecayFactor - previousDecayFactor) < scrollSnapDecayFactorConvergenceThreshold) break; @@ -232,7 +240,11 @@ void BasicScrollingMomentumCalculator::initializeSnapProgressCurve() float BasicScrollingMomentumCalculator::animationProgressAfterElapsedTime(Seconds elapsedTime) const { float timeProgress = clampTo(elapsedTime / scrollSnapAnimationDuration, 0, 1); +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return std::min(1.0, m_snapAnimationCurveMagnitude * (1.0 - pow(m_snapAnimationDecayFactor, -framesPerSecond * scrollSnapAnimationDuration.value() * timeProgress))); +#else return std::min(1.0, m_snapAnimationCurveMagnitude * (1.0 - std::pow(m_snapAnimationDecayFactor, -framesPerSecond * scrollSnapAnimationDuration.value() * timeProgress))); +#endif } }; // namespace WebCore diff --git a/Source/WebCore/platform/calc/CalcOperator.h b/Source/WebCore/platform/calc/CalcOperator.h index 6729b9f4782e2..db7cd8f06e684 100644 --- a/Source/WebCore/platform/calc/CalcOperator.h +++ b/Source/WebCore/platform/calc/CalcOperator.h @@ -133,7 +133,11 @@ double evaluateCalcExpression(CalcOperator calcOperator, const Vector& childr case CalcOperator::Pow: if (children.size() != 2) return std::numeric_limits::quiet_NaN(); +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return pow(evaluate(children[0]), evaluate(children[1])); +#else return std::pow(evaluate(children[0]), evaluate(children[1])); +#endif case CalcOperator::Sqrt: { if (children.size() != 1) return std::numeric_limits::quiet_NaN(); diff --git a/Source/WebCore/platform/graphics/ColorTransferFunctions.h b/Source/WebCore/platform/graphics/ColorTransferFunctions.h index ee36ad9ae0293..a2e2a605b6b4d 100644 --- a/Source/WebCore/platform/graphics/ColorTransferFunctions.h +++ b/Source/WebCore/platform/graphics/ColorTransferFunctions.h @@ -71,7 +71,11 @@ struct SRGBTransferFunction { template T A98RGBTransferFunction::toGammaEncoded(T c) { auto sign = std::signbit(c) ? -1.0f : 1.0f; +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + auto result = pow(std::abs(c), 256.0f / 563.0f) * sign; +#else auto result = std::pow(std::abs(c), 256.0f / 563.0f) * sign; +#endif if constexpr (mode == TransferFunctionMode::Clamped) return clampTo(result, 0, 1); return result; @@ -80,7 +84,11 @@ template T A98RGBTransferFunction T A98RGBTransferFunction::toLinear(T c) { auto sign = std::signbit(c) ? -1.0f : 1.0f; +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + auto result = pow(std::abs(c), 563.0f / 256.0f) * sign; +#else auto result = std::pow(std::abs(c), 563.0f / 256.0f) * sign; +#endif if constexpr (mode == TransferFunctionMode::Clamped) return clampTo(result, 0, 1); return result; @@ -93,14 +101,21 @@ template T ProPhotoRGBTransferFunction(pow(c, 1.0 / gamma), 0, 1); +#else return clampTo(std::pow(c, 1.0 / gamma), 0, 1); +#endif } else { if (std::abs(c) < 1.0 / 512.0) return 16.0 * c; float sign = std::signbit(c) ? -1.0 : 1.0; +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return pow(c, 1.0 / gamma) * sign; +#else return std::pow(c, 1.0 / gamma) * sign; +#endif } } @@ -109,14 +124,21 @@ template T ProPhotoRGBTransferFunction(pow(c, gamma), 0, 1); +#else return clampTo(std::pow(c, gamma), 0, 1); +#endif } else { if (std::abs(c) <= 16.0 / 512.0) return c / 16.0; float sign = std::signbit(c) ? -1.0 : 1.0; +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return pow(c, gamma) * sign; +#else return std::pow(c, gamma) * sign; +#endif } } @@ -127,14 +149,21 @@ template T Rec2020TransferFunction(alpha * pow(c, gamma) - (alpha - 1.0f), 0, 1); +#else return clampTo(alpha * std::pow(c, gamma) - (alpha - 1.0f), 0, 1); +#endif } else { if (std::abs(c) <= beta) return 4.5f * c; float sign = std::signbit(c) ? -1.0 : 1.0; +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return (alpha * pow(c, gamma) - (alpha - 1.0)) * sign; +#else return (alpha * std::pow(c, gamma) - (alpha - 1.0)) * sign; +#endif } } @@ -143,13 +172,21 @@ template T Rec2020TransferFunction(pow((c + alpha - 1.0) / alpha, 1.0 / gamma), 0, 1); +#else return clampTo(std::pow((c + alpha - 1.0) / alpha, 1.0 / gamma), 0, 1); +#endif } else { if (std::abs(c) < beta * 4.5f) return c / 4.5f; float sign = std::signbit(c) ? -1.0 : 1.0; +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return pow((c + alpha - 1.0) / alpha, 1.0 / gamma) * sign; +#else return std::pow((c + alpha - 1.0) / alpha, 1.0 / gamma) * sign; +#endif } } @@ -160,14 +197,22 @@ template T SRGBTransferFunction: if constexpr (mode == TransferFunctionMode::Clamped) { if (c < 0.0031308f) return std::max(12.92f * c, 0); +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return clampTo(1.055f * pow(c, 1.0f / 2.4f) - 0.055f, 0, 1); +#else return clampTo(1.055f * std::pow(c, 1.0f / 2.4f) - 0.055f, 0, 1); +#endif } else { auto sign = std::signbit(c) ? -1.0f : 1.0f; c = std::abs(c); if (c < 0.0031308f) return 12.92f * c * sign; +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return (1.055f * pow(c, 1.0f / 2.4f) - 0.055f) * sign; +#else return (1.055f * std::pow(c, 1.0f / 2.4f) - 0.055f) * sign; +#endif } } @@ -176,14 +221,22 @@ template T SRGBTransferFunction: if constexpr (mode == TransferFunctionMode::Clamped) { if (c <= 0.04045f) return std::max(c / 12.92f, 0); +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return clampTo(pow((c + 0.055f) / 1.055f, 2.4f), 0, 1); +#else return clampTo(std::pow((c + 0.055f) / 1.055f, 2.4f), 0, 1); +#endif } else { auto sign = std::signbit(c) ? -1.0f : 1.0f; c = std::abs(c); if (c <= 0.04045f) return c / 12.92f * sign; +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + return pow((c + 0.055f) / 1.055f, 2.4f) * sign; +#else return std::pow((c + 0.055f) / 1.055f, 2.4f) * sign; +#endif } } diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h index 793d8c88d7f40..acb0657836b42 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.h +++ b/Source/WebCore/platform/graphics/GraphicsContext.h @@ -366,12 +366,6 @@ class GraphicsContext { void setContentfulPaintDetected() { m_contentfulPaintDetected = true; } bool contentfulPaintDetected() const { return m_contentfulPaintDetected; } - // FIXME: Nothing in this section belongs here, and should be moved elsewhere. -#if OS(WINDOWS) - HDC getWindowsContext(const IntRect&, bool supportAlphaBlend); // The passed in rect is used to create a bitmap for compositing inside transparency layers. - void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend); // The passed in HDC should be the one handed back by getWindowsContext. -#endif - IsDeferred deferred() const { return m_isDeferred; } private: virtual void drawNativeImageInternal(NativeImage&, const FloatSize& selfSize, const FloatRect& destRect, const FloatRect& srcRect, ImagePaintingOptions = { }) = 0; diff --git a/Source/WebCore/platform/graphics/PlatformPath.h b/Source/WebCore/platform/graphics/PlatformPath.h index 957283fae1852..59605002bf1c7 100644 --- a/Source/WebCore/platform/graphics/PlatformPath.h +++ b/Source/WebCore/platform/graphics/PlatformPath.h @@ -39,7 +39,7 @@ typedef struct CGPath PlatformPath; typedef PlatformPath* PlatformPathPtr; #elif PLATFORM(QT) /* QPainterPath is valued based */ -typedef const PlatformPath& PlatformPathPtr; +typedef const PlatformPath PlatformPathPtr; #else typedef cairo_t* PlatformPathPtr; #endif diff --git a/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp b/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp index ce85f29f836b2..8b87bdaf837ca 100644 --- a/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp +++ b/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp @@ -41,7 +41,6 @@ #include #if PLATFORM(QT) -#include #include #include #endif @@ -337,6 +336,702 @@ static hb_script_t findScriptForVerticalGlyphSubstitution(hb_face_t* face) return HB_SCRIPT_INVALID; } +/* +This part is shamelessly taken from qharfbuzzng.cpp from QT 6.5.3 code +*/ + +#if PLATFORM(QT) +#include +#include +#include + +static const hb_script_t _qtscript_to_hbscript[] = { + HB_SCRIPT_UNKNOWN, + HB_SCRIPT_INHERITED, + HB_SCRIPT_COMMON, + + HB_SCRIPT_LATIN, + HB_SCRIPT_GREEK, + HB_SCRIPT_CYRILLIC, + HB_SCRIPT_ARMENIAN, + HB_SCRIPT_HEBREW, + HB_SCRIPT_ARABIC, + HB_SCRIPT_SYRIAC, + HB_SCRIPT_THAANA, + HB_SCRIPT_DEVANAGARI, + HB_SCRIPT_BENGALI, + HB_SCRIPT_GURMUKHI, + HB_SCRIPT_GUJARATI, + HB_SCRIPT_ORIYA, + HB_SCRIPT_TAMIL, + HB_SCRIPT_TELUGU, + HB_SCRIPT_KANNADA, + HB_SCRIPT_MALAYALAM, + HB_SCRIPT_SINHALA, + HB_SCRIPT_THAI, + HB_SCRIPT_LAO, + HB_SCRIPT_TIBETAN, + HB_SCRIPT_MYANMAR, + HB_SCRIPT_GEORGIAN, + HB_SCRIPT_HANGUL, + HB_SCRIPT_ETHIOPIC, + HB_SCRIPT_CHEROKEE, + HB_SCRIPT_CANADIAN_SYLLABICS, + HB_SCRIPT_OGHAM, + HB_SCRIPT_RUNIC, + HB_SCRIPT_KHMER, + HB_SCRIPT_MONGOLIAN, + HB_SCRIPT_HIRAGANA, + HB_SCRIPT_KATAKANA, + HB_SCRIPT_BOPOMOFO, + HB_SCRIPT_HAN, + HB_SCRIPT_YI, + HB_SCRIPT_OLD_ITALIC, + HB_SCRIPT_GOTHIC, + HB_SCRIPT_DESERET, + HB_SCRIPT_TAGALOG, + HB_SCRIPT_HANUNOO, + HB_SCRIPT_BUHID, + HB_SCRIPT_TAGBANWA, + HB_SCRIPT_COPTIC, + + // Unicode 4.0 additions + HB_SCRIPT_LIMBU, + HB_SCRIPT_TAI_LE, + HB_SCRIPT_LINEAR_B, + HB_SCRIPT_UGARITIC, + HB_SCRIPT_SHAVIAN, + HB_SCRIPT_OSMANYA, + HB_SCRIPT_CYPRIOT, + HB_SCRIPT_BRAILLE, + + // Unicode 4.1 additions + HB_SCRIPT_BUGINESE, + HB_SCRIPT_NEW_TAI_LUE, + HB_SCRIPT_GLAGOLITIC, + HB_SCRIPT_TIFINAGH, + HB_SCRIPT_SYLOTI_NAGRI, + HB_SCRIPT_OLD_PERSIAN, + HB_SCRIPT_KHAROSHTHI, + + // Unicode 5.0 additions + HB_SCRIPT_BALINESE, + HB_SCRIPT_CUNEIFORM, + HB_SCRIPT_PHOENICIAN, + HB_SCRIPT_PHAGS_PA, + HB_SCRIPT_NKO, + + // Unicode 5.1 additions + HB_SCRIPT_SUNDANESE, + HB_SCRIPT_LEPCHA, + HB_SCRIPT_OL_CHIKI, + HB_SCRIPT_VAI, + HB_SCRIPT_SAURASHTRA, + HB_SCRIPT_KAYAH_LI, + HB_SCRIPT_REJANG, + HB_SCRIPT_LYCIAN, + HB_SCRIPT_CARIAN, + HB_SCRIPT_LYDIAN, + HB_SCRIPT_CHAM, + + // Unicode 5.2 additions + HB_SCRIPT_TAI_THAM, + HB_SCRIPT_TAI_VIET, + HB_SCRIPT_AVESTAN, + HB_SCRIPT_EGYPTIAN_HIEROGLYPHS, + HB_SCRIPT_SAMARITAN, + HB_SCRIPT_LISU, + HB_SCRIPT_BAMUM, + HB_SCRIPT_JAVANESE, + HB_SCRIPT_MEETEI_MAYEK, + HB_SCRIPT_IMPERIAL_ARAMAIC, + HB_SCRIPT_OLD_SOUTH_ARABIAN, + HB_SCRIPT_INSCRIPTIONAL_PARTHIAN, + HB_SCRIPT_INSCRIPTIONAL_PAHLAVI, + HB_SCRIPT_OLD_TURKIC, + HB_SCRIPT_KAITHI, + + // Unicode 6.0 additions + HB_SCRIPT_BATAK, + HB_SCRIPT_BRAHMI, + HB_SCRIPT_MANDAIC, + + // Unicode 6.1 additions + HB_SCRIPT_CHAKMA, + HB_SCRIPT_MEROITIC_CURSIVE, + HB_SCRIPT_MEROITIC_HIEROGLYPHS, + HB_SCRIPT_MIAO, + HB_SCRIPT_SHARADA, + HB_SCRIPT_SORA_SOMPENG, + HB_SCRIPT_TAKRI, + + // Unicode 7.0 additions + HB_SCRIPT_CAUCASIAN_ALBANIAN, + HB_SCRIPT_BASSA_VAH, + HB_SCRIPT_DUPLOYAN, + HB_SCRIPT_ELBASAN, + HB_SCRIPT_GRANTHA, + HB_SCRIPT_PAHAWH_HMONG, + HB_SCRIPT_KHOJKI, + HB_SCRIPT_LINEAR_A, + HB_SCRIPT_MAHAJANI, + HB_SCRIPT_MANICHAEAN, + HB_SCRIPT_MENDE_KIKAKUI, + HB_SCRIPT_MODI, + HB_SCRIPT_MRO, + HB_SCRIPT_OLD_NORTH_ARABIAN, + HB_SCRIPT_NABATAEAN, + HB_SCRIPT_PALMYRENE, + HB_SCRIPT_PAU_CIN_HAU, + HB_SCRIPT_OLD_PERMIC, + HB_SCRIPT_PSALTER_PAHLAVI, + HB_SCRIPT_SIDDHAM, + HB_SCRIPT_KHUDAWADI, + HB_SCRIPT_TIRHUTA, + HB_SCRIPT_WARANG_CITI, + + // Unicode 8.0 additions + HB_SCRIPT_AHOM, + HB_SCRIPT_ANATOLIAN_HIEROGLYPHS, + HB_SCRIPT_HATRAN, + HB_SCRIPT_MULTANI, + HB_SCRIPT_OLD_HUNGARIAN, + HB_SCRIPT_SIGNWRITING, + + // Unicode 9.0 additions + HB_SCRIPT_ADLAM, + HB_SCRIPT_BHAIKSUKI, + HB_SCRIPT_MARCHEN, + HB_SCRIPT_NEWA, + HB_SCRIPT_OSAGE, + HB_SCRIPT_TANGUT, + + // Unicode 10.0 additions + HB_SCRIPT_MASARAM_GONDI, + HB_SCRIPT_NUSHU, + HB_SCRIPT_SOYOMBO, + HB_SCRIPT_ZANABAZAR_SQUARE, + + // Unicode 11.0 additions + HB_SCRIPT_DOGRA, + HB_SCRIPT_GUNJALA_GONDI, + HB_SCRIPT_HANIFI_ROHINGYA, + HB_SCRIPT_MAKASAR, + HB_SCRIPT_MEDEFAIDRIN, + HB_SCRIPT_OLD_SOGDIAN, + HB_SCRIPT_SOGDIAN, + + // Unicode 12.0 additions + HB_SCRIPT_ELYMAIC, + HB_SCRIPT_NANDINAGARI, + HB_SCRIPT_NYIAKENG_PUACHUE_HMONG, + HB_SCRIPT_WANCHO, + + // Unicode 13.0 additions (not present in harfbuzz-ng 2.6.6 and earlier) +#if !HB_VERSION_ATLEAST(2, 6, 7) + hb_script_t(HB_TAG('C', 'h', 'r', 's')), // Script_Chorasmian + hb_script_t(HB_TAG('D', 'i', 'a', 'k')), // Script_DivesAkuru + hb_script_t(HB_TAG('K', 'i', 't', 's')), // Script_KhitanSmallScript + hb_script_t(HB_TAG('Y', 'e', 'z', 'i')), // Script_Yezidi +#else + HB_SCRIPT_CHORASMIAN, + HB_SCRIPT_DIVES_AKURU, + HB_SCRIPT_KHITAN_SMALL_SCRIPT, + HB_SCRIPT_YEZIDI, +#endif + // Unicode 14.0 additions (not present in harfbuzz-ng 2.9.1 and earlier) +#if !HB_VERSION_ATLEAST(3, 0, 0) + hb_script_t(HB_TAG('C','p','m','n')), // Script_CyproMinoan + hb_script_t(HB_TAG('O','u','g','r')), // Script_OldUyghur + hb_script_t(HB_TAG('T','n','s','a')), // Script_Tangsa + hb_script_t(HB_TAG('T','o','t','o')), // Script_Toto + hb_script_t(HB_TAG('V','i','t','h')), // Script_Vithkuqi +#else + HB_SCRIPT_CYPRO_MINOAN, + HB_SCRIPT_OLD_UYGHUR, + HB_SCRIPT_TANGSA, + HB_SCRIPT_TOTO, + HB_SCRIPT_VITHKUQI, +#endif + // Unicode 15.0 additions (not present in harfbuzz-ng 5.1.0 and earlier) +#if !HB_VERSION_ATLEAST(5, 2, 0) + hb_script_t(HB_TAG('K','a','w','i')), // Script_Kawi + hb_script_t(HB_TAG('N','a','g','m')), // Script_NagMundari +#else + HB_SCRIPT_KAWI, + HB_SCRIPT_NAG_MUNDARI, +#endif +}; +static_assert(QChar::ScriptCount == sizeof(_qtscript_to_hbscript) / sizeof(_qtscript_to_hbscript[0])); + +hb_script_t hb_qt_script_to_script(QChar::Script script) +{ + return _qtscript_to_hbscript[script]; +} + +QChar::Script hb_qt_script_from_script(hb_script_t script) +{ + uint i = QChar::ScriptCount - 1; + while (i > QChar::Script_Unknown && _qtscript_to_hbscript[i] != script) + --i; + return QChar::Script(i); +} + + +static hb_unicode_combining_class_t +_hb_qt_unicode_combining_class(hb_unicode_funcs_t * /*ufuncs*/, + hb_codepoint_t unicode, + void * /*user_data*/) +{ + return hb_unicode_combining_class_t(QChar::combiningClass(unicode)); +} + +static const hb_unicode_general_category_t _qtcategory_to_hbcategory[] = { + HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK, // Mn + HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK, // Mc + HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK, // Me + + HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER, // Nd + HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER, // Nl + HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER, // No + + HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR, // Zs + HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR, // Zl + HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR, // Zp + + HB_UNICODE_GENERAL_CATEGORY_CONTROL, // Cc + HB_UNICODE_GENERAL_CATEGORY_FORMAT, // Cf + HB_UNICODE_GENERAL_CATEGORY_SURROGATE, // Cs + HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE, // Co + HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED, // Cn + + HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER, // Lu + HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER, // Ll + HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER, // Lt + HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER, // Lm + HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER, // Lo + + HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION, // Pc + HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION, // Pd + HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION, // Ps + HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION, // Pe + HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION, // Pi + HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION, // Pf + HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION, // Po + + HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL, // Sm + HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL, // Sc + HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL, // Sk + HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL // So +}; + +static hb_unicode_general_category_t +_hb_qt_unicode_general_category(hb_unicode_funcs_t * /*ufuncs*/, + hb_codepoint_t unicode, + void * /*user_data*/) +{ + return _qtcategory_to_hbcategory[QChar::category(unicode)]; +} + +static hb_codepoint_t +_hb_qt_unicode_mirroring(hb_unicode_funcs_t * /*ufuncs*/, + hb_codepoint_t unicode, + void * /*user_data*/) +{ + return QChar::mirroredChar(unicode); +} + +static hb_script_t +_hb_qt_unicode_script(hb_unicode_funcs_t * /*ufuncs*/, + hb_codepoint_t unicode, + void * /*user_data*/) +{ + return _qtscript_to_hbscript[QChar::script(unicode)]; +} + +static hb_bool_t +_hb_qt_unicode_compose(hb_unicode_funcs_t * /*ufuncs*/, + hb_codepoint_t a, hb_codepoint_t b, + hb_codepoint_t *ab, + void * /*user_data*/) +{ + // ### optimize + QString s; + s.reserve(4); + s += QChar::fromUcs4(a); + s += QChar::fromUcs4(b); + QString normalized = s.normalized(QString::NormalizationForm_C); + + QStringIterator it(normalized); + Q_ASSERT(it.hasNext()); // size>0 + *ab = it.next(); + + return !it.hasNext(); // size==1 +} + +static hb_bool_t +_hb_qt_unicode_decompose(hb_unicode_funcs_t * /*ufuncs*/, + hb_codepoint_t ab, + hb_codepoint_t *a, hb_codepoint_t *b, + void * /*user_data*/) +{ + // ### optimize + if (QChar::decompositionTag(ab) != QChar::Canonical) // !NFD + return false; + + QString normalized = QChar::decomposition(ab); + if (normalized.isEmpty()) + return false; + + QStringIterator it(normalized); + Q_ASSERT(it.hasNext()); // size>0 + *a = it.next(); + + if (!it.hasNext()) { // size==1 + *b = 0; + return *a != ab; + } + + // size>1 + *b = it.next(); + if (!it.hasNext()) { // size==2 + // Here's the ugly part: if ab decomposes to a single character and + // that character decomposes again, we have to detect that and undo + // the second part :-( + const QString recomposed = normalized.normalized(QString::NormalizationForm_C); + QStringIterator jt(recomposed); + Q_ASSERT(jt.hasNext()); // size>0 + const hb_codepoint_t c = jt.next(); + if (c != *a && c != ab) { + *a = c; + *b = 0; + } + return true; + } + + // size>2 + // If decomposed to more than two characters, take the last one, + // and recompose the rest to get the first component + do { + *b = it.next(); + } while (it.hasNext()); + normalized.chop(QChar::requiresSurrogates(*b) ? 2 : 1); + const QString recomposed = normalized.normalized(QString::NormalizationForm_C); + QStringIterator jt(recomposed); + Q_ASSERT(jt.hasNext()); // size>0 + // We expect that recomposed has exactly one character now + *a = jt.next(); + return true; +} + + +struct _hb_unicode_funcs_t { + _hb_unicode_funcs_t() + { + funcs = hb_unicode_funcs_create(NULL); + hb_unicode_funcs_set_combining_class_func(funcs, _hb_qt_unicode_combining_class, NULL, NULL); + hb_unicode_funcs_set_general_category_func(funcs, _hb_qt_unicode_general_category, NULL, NULL); + hb_unicode_funcs_set_mirroring_func(funcs, _hb_qt_unicode_mirroring, NULL, NULL); + hb_unicode_funcs_set_script_func(funcs, _hb_qt_unicode_script, NULL, NULL); + hb_unicode_funcs_set_compose_func(funcs, _hb_qt_unicode_compose, NULL, NULL); + hb_unicode_funcs_set_decompose_func(funcs, _hb_qt_unicode_decompose, NULL, NULL); + } + ~_hb_unicode_funcs_t() + { + hb_unicode_funcs_destroy(funcs); + } + + hb_unicode_funcs_t *funcs; +}; + +static _hb_unicode_funcs_t qt_ufuncs; + +hb_unicode_funcs_t *hb_qt_get_unicode_funcs() +{ + return qt_ufuncs.funcs; +} + + +// Font routines + +static hb_user_data_key_t _useDesignMetricsKey; + +void hb_qt_font_set_use_design_metrics(hb_font_t *font, uint value) +{ + hb_font_set_user_data(font, &_useDesignMetricsKey, (void *)quintptr(value), NULL, true); +} + +uint hb_qt_font_get_use_design_metrics(hb_font_t *font) +{ + return quintptr(hb_font_get_user_data(font, &_useDesignMetricsKey)); +} + + +static hb_bool_t +_hb_qt_get_font_h_extents(hb_font_t * /*font*/, void *font_data, + hb_font_extents_t *metrics, + void * /*user_data*/) +{ + QFontEngine *fe = static_cast(font_data); + Q_ASSERT(fe); + + metrics->ascender = fe->ascent().value(); + metrics->descender = fe->descent().value(); + metrics->line_gap = fe->leading().value(); + + return true; +} + +static hb_bool_t +_hb_qt_font_get_nominal_glyph(hb_font_t * /*font*/, void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t *glyph, + void * /*user_data*/) +{ + QFontEngine *fe = static_cast(font_data); + Q_ASSERT(fe); + + *glyph = fe->glyphIndex(unicode); + + return *glyph != 0; +} + +static hb_bool_t +_hb_qt_font_get_variation_glyph(hb_font_t * /*font*/, void *font_data, + hb_codepoint_t unicode, hb_codepoint_t /*variation_selector*/, + hb_codepoint_t *glyph, + void * /*user_data*/) +{ + QFontEngine *fe = static_cast(font_data); + Q_ASSERT(fe); + + // ### TODO add support for variation selectors + *glyph = fe->glyphIndex(unicode); + + return *glyph != 0; +} + +static hb_position_t +_hb_qt_font_get_glyph_h_advance(hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + void * /*user_data*/) +{ + QFontEngine *fe = static_cast(font_data); + Q_ASSERT(fe); + + QFixed advance; + + QGlyphLayout g; + g.numGlyphs = 1; + g.glyphs = &glyph; + g.advances = &advance; + + fe->recalcAdvances(&g, QFontEngine::ShaperFlags(hb_qt_font_get_use_design_metrics(font))); + + return advance.value(); +} + +static hb_position_t +_hb_qt_font_get_glyph_h_kerning(hb_font_t *font, void *font_data, + hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, + void * /*user_data*/) +{ + QFontEngine *fe = static_cast(font_data); + Q_ASSERT(fe); + + glyph_t glyphs[2] = { first_glyph, second_glyph }; + QFixed advance; + + QGlyphLayout g; + g.numGlyphs = 2; + g.glyphs = glyphs; + g.advances = &advance; + + fe->doKerning(&g, QFontEngine::ShaperFlags(hb_qt_font_get_use_design_metrics(font))); + + return advance.value(); +} + +static hb_bool_t +_hb_qt_font_get_glyph_extents(hb_font_t * /*font*/, void *font_data, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + void * /*user_data*/) +{ + QFontEngine *fe = static_cast(font_data); + Q_ASSERT(fe); + + glyph_metrics_t gm = fe->boundingBox(glyph); + + extents->x_bearing = gm.x.value(); + extents->y_bearing = gm.y.value(); + extents->width = gm.width.value(); + extents->height = gm.height.value(); + + return true; +} + +static hb_bool_t +_hb_qt_font_get_glyph_contour_point(hb_font_t * /*font*/, void *font_data, + hb_codepoint_t glyph, + unsigned int point_index, hb_position_t *x, hb_position_t *y, + void * /*user_data*/) +{ + QFontEngine *fe = static_cast(font_data); + Q_ASSERT(fe); + + QFixed xpos, ypos; + quint32 numPoints = 1; + if (Q_LIKELY(fe->getPointInOutline(glyph, 0, point_index, &xpos, &ypos, &numPoints) == 0)) { + *x = xpos.value(); + *y = ypos.value(); + return true; + } + + *x = *y = 0; + return false; +} + + +struct _hb_qt_font_funcs_t { + _hb_qt_font_funcs_t() + { + funcs = hb_font_funcs_create(); + + hb_font_funcs_set_font_h_extents_func(funcs, _hb_qt_get_font_h_extents, NULL, NULL); + hb_font_funcs_set_nominal_glyph_func(funcs, _hb_qt_font_get_nominal_glyph, NULL, NULL); + hb_font_funcs_set_variation_glyph_func(funcs, _hb_qt_font_get_variation_glyph, NULL, NULL); + hb_font_funcs_set_glyph_h_advance_func(funcs, _hb_qt_font_get_glyph_h_advance, NULL, NULL); + hb_font_funcs_set_glyph_h_kerning_func(funcs, _hb_qt_font_get_glyph_h_kerning, NULL, NULL); + hb_font_funcs_set_glyph_extents_func(funcs, _hb_qt_font_get_glyph_extents, NULL, NULL); + hb_font_funcs_set_glyph_contour_point_func(funcs, _hb_qt_font_get_glyph_contour_point, NULL, NULL); + + hb_font_funcs_make_immutable(funcs); + } + ~_hb_qt_font_funcs_t() + { + hb_font_funcs_destroy(funcs); + } + + hb_font_funcs_t *funcs; +}; + +static _hb_qt_font_funcs_t qt_ffuncs; + +static hb_blob_t * +_hb_qt_reference_table(hb_face_t * /*face*/, hb_tag_t tag, void *user_data) +{ + QFontEngine::FaceData *data = static_cast(user_data); + Q_ASSERT(data); + + qt_get_font_table_func_t get_font_table = data->get_font_table; + Q_ASSERT(get_font_table); + + uint length = 0; + if (Q_UNLIKELY(!get_font_table(data->user_data, tag, 0, &length))) + return hb_blob_get_empty(); + + char *buffer = static_cast(malloc(length)); + if (q_check_ptr(buffer) == nullptr) + return nullptr; + + if (Q_UNLIKELY(!get_font_table(data->user_data, tag, reinterpret_cast(buffer), &length))) + return nullptr; + + return hb_blob_create(const_cast(buffer), length, + HB_MEMORY_MODE_WRITABLE, + buffer, free); +} + +static inline hb_face_t * +_hb_qt_face_create(QFontEngine *fe) +{ + QFontEngine::FaceData *data = static_cast(malloc(sizeof(QFontEngine::FaceData))); + Q_CHECK_PTR(data); + data->user_data = fe->faceData.user_data; + data->get_font_table = fe->faceData.get_font_table; + + hb_face_t *face = hb_face_create_for_tables(_hb_qt_reference_table, (void *)data, free); + + hb_face_set_index(face, fe->faceId().index); + hb_face_set_upem(face, fe->emSquareSize().truncate()); + + return face; +} + +static void +_hb_qt_face_release(void *user_data) +{ + hb_face_destroy(static_cast(user_data)); +} + +hb_face_t *hb_qt_face_get_for_engine(QFontEngine *fe) +{ + Q_ASSERT(fe && fe->type() != QFontEngine::Multi); + + /* + Two problems why this code is disabled (and is causing some memory leakage, but currently no ideas how to solve it: + 1) if fe->face_ is already created inside QFontEngine not by this code, but internally by QT - it is incompatible with WebKit and it will crash + 2) if QFontEngine is destroyed and we have our face pointer inside it (bye-bye) crash again. + Currently i have no idea how to track life-time of a face and font and dispose of them in safely manner. + */ + + //if (Q_UNLIKELY(!fe->face_)) + //fe->face_ = QFontEngine::Holder(_hb_qt_face_create(fe), _hb_qt_face_release); + + //return static_cast(fe->face_.get()); + + return _hb_qt_face_create(fe); +} + + +static inline hb_font_t * +_hb_qt_font_create(QFontEngine *fe) +{ + //Hopefully will minimise memory leaking by using HbUniquePtr here. + HbUniquePtr face(hb_qt_face_get_for_engine(fe)); + + hb_font_t *font = hb_font_create(face.get()); + + const qreal y_ppem = fe->fontDef.pixelSize; + const qreal x_ppem = (fe->fontDef.pixelSize * fe->fontDef.stretch) / 100.0; + + hb_font_set_funcs(font, qt_ffuncs.funcs, fe, nullptr); + hb_font_set_scale(font, QFixed::fromReal(x_ppem).value(), -QFixed::fromReal(y_ppem).value()); + hb_font_set_ppem(font, int(x_ppem), int(y_ppem)); + + hb_font_set_ptem(font, fe->fontDef.pointSize); + + return font; +} + +static void +_hb_qt_font_release(void *user_data) +{ + hb_font_destroy(static_cast(user_data)); +} + +hb_font_t *hb_qt_font_get_for_engine(QFontEngine *fe) +{ + Q_ASSERT(fe && fe->type() != QFontEngine::Multi); + + /* + Two problems why this code is disabled (and is causing some memory leakage, but currently no ideas how to solve it: + 1) if fe->face_ is already created inside QFontEngine not by this code, but internally by QT - it is incompatible with WebKit and it will crash + 2) if QFontEngine is destroyed and we have our face pointer inside it (bye-bye) crash again. + Currently i have no idea how to track life-time of a face and font and dispose of them in safely manner. + */ + + //if (Q_UNLIKELY(!fe->font_)) + //fe->font_ = QFontEngine::Holder(_hb_qt_font_create(fe), _hb_qt_font_release); + + //return static_cast(fe->font_.get()); + + return _hb_qt_font_create(fe); +} + +#endif //PLATFORM(QT) + void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* characters, unsigned length, unsigned stringLocation, const Font* font) { if (!font) { @@ -397,20 +1092,40 @@ void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cha #elif PLATFORM(QT) const QRawFont& rawFont = fontPlatformData.rawFont(); QFontEngine* fe = QRawFontPrivate::get(rawFont)->fontEngine; + + /* + NakedPtr blob = hb_face_reference_blob(hb_qt_face_get_for_engine(fe)); + HbUniquePtr face(hb_face_create(blob.get(), 0)); + HbUniquePtr harfBuzzFont(hb_font_create(face.get())); + + const float size = fontPlatformData.size(); + if (floorf(size) == size) + hb_font_set_ppem(harfBuzzFont.get(), size, size); + int scale = floatToHarfBuzzPosition(size); + hb_font_set_scale(harfBuzzFont.get(), scale, scale); + + hb_font_make_immutable(harfBuzzFont.get()); + */ + //qDebug() << Q_FUNC_INFO << __LINE__ << fe << fe->type(); - hb_font_t* fnt = hb_qt_font_get_for_engine(fe); + //hb_font_t* fnt = hb_qt_font_get_for_engine(fe); //qDebug() << Q_FUNC_INFO << __LINE__ << "hb_qt_font_get_for_engine" << fnt; //qDebug() << Q_FUNC_INFO << __LINE__ << hb_font_get_face(fnt); - -// qDebug() << Q_FUNC_INFO << __LINE__ << fe->harfbuzzFace(); + //qDebug() << Q_FUNC_INFO << __LINE__ << fe->harfbuzzFace(); //qDebug() << Q_FUNC_INFO << __LINE__ << "hb_qt_face_get_for_engine" << hb_qt_face_get_for_engine(fe); -// qDebug() << Q_FUNC_INFO << __LINE__ << hb_qt_font_get_for_engine(fe); -// qDebug() << Q_FUNC_INFO << __LINE__ << hb_font_get_face(hb_qt_font_get_for_engine(fe)); - NakedPtr face(hb_qt_face_get_for_engine(fe)); - NakedPtr harfBuzzFont(hb_qt_font_get_for_engine(fe)); -// qDebug() << Q_FUNC_INFO << __LINE__ << face.get(); -// qDebug() << Q_FUNC_INFO << __LINE__ << harfBuzzFont.get(); -// qDebug() << Q_FUNC_INFO << __LINE__ << hb_font_get_face(harfBuzzFont.get()); + //qDebug() << Q_FUNC_INFO << __LINE__ << hb_qt_font_get_for_engine(fe); + //qDebug() << Q_FUNC_INFO << __LINE__ << hb_font_get_face(hb_qt_font_get_for_engine(fe)); + //qDebug() << Q_FUNC_INFO << __LINE__ << face.get(); + //qDebug() << Q_FUNC_INFO << __LINE__ << harfBuzzFont.get(); + //qDebug() << Q_FUNC_INFO << __LINE__ << hb_font_get_face(harfBuzzFont.get()); + + /* + That's why here i'm using HbUniquePtr in the hopes that it will track and delete face and font when not in use. + */ + + HbUniquePtr face(hb_qt_face_get_for_engine(fe)); + HbUniquePtr harfBuzzFont(hb_qt_font_get_for_engine(fe)); + #endif auto features = fontFeatures(m_font, fontPlatformData); @@ -429,6 +1144,7 @@ void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cha // Leaving direction to HarfBuzz to guess is *really* bad, but will do for now. hb_buffer_guess_segment_properties(buffer.get()); } + hb_buffer_add_utf16(buffer.get(), reinterpret_cast(characters), length, run.startIndex, run.endIndex - run.startIndex); hb_shape(harfBuzzFont.get(), buffer.get(), features.isEmpty() ? nullptr : features.data(), features.size()); diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.h b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.h index 0d80d5e5a0c3d..9244aca2ee7e8 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.h +++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.h @@ -90,6 +90,12 @@ class WEBCORE_EXPORT GraphicsContextQt final : public GraphicsContext { void setURLForRect(const URL& url, const FloatRect& rect) final; RenderingMode renderingMode() const final; + + // FIXED: Moved from GraphicsContext.h to GraphicContextQt.h, probably belongs here. +#if OS(WINDOWS) + HDC getWindowsContext(const IntRect&, bool supportAlphaBlend); // The passed in rect is used to create a bitmap for compositing inside transparency layers. + void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend); // The passed in HDC should be the one handed back by getWindowsContext. +#endif using GraphicsContext::scale; void scale(const FloatSize&) final; diff --git a/Source/WebCore/platform/qt/PlatformGestureEvent.h b/Source/WebCore/platform/qt/PlatformGestureEvent.h index 1a0006842378a..5718715358049 100644 --- a/Source/WebCore/platform/qt/PlatformGestureEvent.h +++ b/Source/WebCore/platform/qt/PlatformGestureEvent.h @@ -37,7 +37,7 @@ namespace WebCore { class PlatformGestureEvent : public PlatformEvent { public: PlatformGestureEvent() - : PlatformEvent(PlatformEvent::GestureTap) + : PlatformEvent(PlatformEventType::GestureTap) { } diff --git a/Source/WebCore/platform/qt/PlatformScreenQt.cpp b/Source/WebCore/platform/qt/PlatformScreenQt.cpp index 3e53030905c1c..168db21d361e2 100644 --- a/Source/WebCore/platform/qt/PlatformScreenQt.cpp +++ b/Source/WebCore/platform/qt/PlatformScreenQt.cpp @@ -41,7 +41,7 @@ #include #if ENABLE(TOUCH_EVENTS) -#include +#include #endif namespace WebCore { @@ -118,7 +118,14 @@ bool screenIsTouchPrimaryInputDevice() bool screenHasTouchDevice() { - return !QTouchDevice::devices().isEmpty(); + for(auto dev : QInputDevice::devices()) + { + if(dev->type() == QInputDevice::DeviceType::TouchScreen) + { + return true; + } + } + return false; } #endif diff --git a/Source/WebCore/rendering/HitTestRequest.h b/Source/WebCore/rendering/HitTestRequest.h index f719cf3369518..07d02dfda6a2b 100644 --- a/Source/WebCore/rendering/HitTestRequest.h +++ b/Source/WebCore/rendering/HitTestRequest.h @@ -29,7 +29,7 @@ namespace WebCore { class HitTestRequest { public: - enum class Type { + enum class Type : int { ReadOnly = 1 << 0, Active = 1 << 1, Move = 1 << 2, @@ -51,7 +51,7 @@ class HitTestRequest { IncludeAllElementsUnderPoint = 1 << 16, PenEvent = 1 << 17, }; - + HitTestRequest(OptionSet type = { Type::ReadOnly, Type::Active, Type::DisallowUserAgentShadowContent }) : m_type { type } { @@ -89,4 +89,59 @@ class HitTestRequest { OptionSet m_type; }; + inline constexpr HitTestRequest::Type + operator&(HitTestRequest::Type x, HitTestRequest::Type y) + { + return static_cast + (static_cast(x) & static_cast(y)); + } + + inline constexpr HitTestRequest::Type + operator|(HitTestRequest::Type x, HitTestRequest::Type y) + { + return static_cast + (static_cast(x) | static_cast(y)); + } + + inline constexpr HitTestRequest::Type + operator^(HitTestRequest::Type x, HitTestRequest::Type y) + { + return static_cast + (static_cast(x) ^ static_cast(y)); + } + + inline constexpr HitTestRequest::Type + operator~(HitTestRequest::Type x) + { + return static_cast(~static_cast(x)); + } + + inline constexpr HitTestRequest::Type + operator!(HitTestRequest::Type x) + { + return static_cast(!static_cast(x)); + } + + inline HitTestRequest::Type & + operator&=(HitTestRequest::Type & x, HitTestRequest::Type y) + { + x = x & y; + return x; + } + + inline HitTestRequest::Type & + operator|=(HitTestRequest::Type & x, HitTestRequest::Type y) + { + x = x | y; + return x; + } + + inline HitTestRequest::Type & + operator^=(HitTestRequest::Type & x, HitTestRequest::Type y) + { + x = x ^ y; + return x; + } + + } // namespace WebCore diff --git a/Source/WebCore/rendering/style/StyleGradientImage.cpp b/Source/WebCore/rendering/style/StyleGradientImage.cpp index d38b2ad775992..9a5fa92063054 100644 --- a/Source/WebCore/rendering/style/StyleGradientImage.cpp +++ b/Source/WebCore/rendering/style/StyleGradientImage.cpp @@ -552,7 +552,11 @@ GradientColorStops StyleGradientImage::computeStops(GradientAdapter& gradientAda // calculate colors for (size_t y = 0; y < 9; ++y) { float relativeOffset = (*newStops[y].offset - offset1) / (offset2 - offset1); +#if COMPILER(MINGW64) && (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) + float multiplier = pow(relativeOffset, std::log(.5f) / std::log(midpoint)); +#else float multiplier = std::pow(relativeOffset, std::log(.5f) / std::log(midpoint)); +#endif newStops[y].color = interpolateColors(m_colorInterpolationMethod.method, color1, 1.0f - multiplier, color2, multiplier); } diff --git a/Source/WebInspectorUI/Scripts/copy-user-interface-resources.pl b/Source/WebInspectorUI/Scripts/copy-user-interface-resources.pl index bd83c4a32ddf0..c37bf75c192db 100755 --- a/Source/WebInspectorUI/Scripts/copy-user-interface-resources.pl +++ b/Source/WebInspectorUI/Scripts/copy-user-interface-resources.pl @@ -211,6 +211,7 @@ ($) # Always refer to the copy in derived sources so the order of replacements does not matter. make_path($derivedSourcesDir); my $derivedSourcesMainHTML = File::Spec->catfile($derivedSourcesDir, 'Main.html'); +unlink(File::Spec->catfile($derivedSourcesDir, 'Main.html')); copy(File::Spec->catfile($uiRoot, 'Main.html'), File::Spec->catfile($derivedSourcesDir, 'Main.html')) or die "Copy failed: $!"; if (!$shouldIncludeBrowserInspectorFrontendHost) { diff --git a/Source/WebKitLegacy/qt/WebCoreSupport/ChromeClientQt.h b/Source/WebKitLegacy/qt/WebCoreSupport/ChromeClientQt.h index d5547432f40e1..e8ce3642b2060 100644 --- a/Source/WebKitLegacy/qt/WebCoreSupport/ChromeClientQt.h +++ b/Source/WebKitLegacy/qt/WebCoreSupport/ChromeClientQt.h @@ -152,7 +152,7 @@ class ChromeClientQt final : public ChromeClient { #endif #if ENABLE(TOUCH_EVENTS) - void needTouchEvents(bool) final { } + void needTouchEvents(bool) { } #endif void isPlayingMediaDidChange(MediaProducerMediaStateFlags) final; diff --git a/Source/WebKitLegacy/qt/WebCoreSupport/QWebFrameAdapter.cpp b/Source/WebKitLegacy/qt/WebCoreSupport/QWebFrameAdapter.cpp index 0662e99b97da1..1f65609f0028a 100644 --- a/Source/WebKitLegacy/qt/WebCoreSupport/QWebFrameAdapter.cpp +++ b/Source/WebKitLegacy/qt/WebCoreSupport/QWebFrameAdapter.cpp @@ -63,7 +63,7 @@ #endif #if ENABLE(QT_GESTURE_EVENTS) -#include "PlatformGestureEvent.h" +#include #include "WebEventConversion.h" #endif diff --git a/Source/WebKitLegacy/qt/WebCoreSupport/QWebPageAdapter.cpp b/Source/WebKitLegacy/qt/WebCoreSupport/QWebPageAdapter.cpp index 561720977d5a6..f5044c033d678 100644 --- a/Source/WebKitLegacy/qt/WebCoreSupport/QWebPageAdapter.cpp +++ b/Source/WebKitLegacy/qt/WebCoreSupport/QWebPageAdapter.cpp @@ -96,6 +96,7 @@ #include #include #include +#include #include #include #include @@ -1541,7 +1542,7 @@ bool QWebPageAdapter::handleShortcutOverrideEvent(QKeyEvent* event) bool QWebPageAdapter::touchEvent(QTouchEvent* event) { #if ENABLE(TOUCH_EVENTS) - Frame* frame = mainFrameAdapter().frame; + WebCore::LocalFrame* frame = mainFrameAdapter().frame; if (!frame->view() || !frame->document()) return false; @@ -1554,7 +1555,7 @@ bool QWebPageAdapter::touchEvent(QTouchEvent* event) event->setAccepted(true); // Return whether the default action was cancelled in the JS event handler - return frame->eventHandler().handleTouchEvent(convertTouchEvent(event)); + return frame->eventHandler().handleTouchEvent(convertTouchEvent(event)).wasHandled(); #else event->ignore(); return false; diff --git a/Source/WebKitLegacy/qt/WebCoreSupport/WebEventConversion.cpp b/Source/WebKitLegacy/qt/WebCoreSupport/WebEventConversion.cpp index 1be23b4d2f542..b449394366476 100644 --- a/Source/WebKitLegacy/qt/WebCoreSupport/WebEventConversion.cpp +++ b/Source/WebKitLegacy/qt/WebCoreSupport/WebEventConversion.cpp @@ -210,7 +210,7 @@ WebKitPlatformTouchEvent::WebKitPlatformTouchEvent(QTouchEvent* event) m_modifiers = mouseEventModifiersFromQtKeyboardModifiers(event->modifiers()); - m_timestamp = WTF::currentTime(); + m_timestamp = WallTime::now(); } WebKitPlatformTouchPoint::WebKitPlatformTouchPoint(const QTouchEvent::TouchPoint& point, State state) @@ -221,10 +221,10 @@ WebKitPlatformTouchPoint::WebKitPlatformTouchPoint(const QTouchEvent::TouchPoint m_screenPos = point.screenPos().toPoint(); m_pos = point.pos().toPoint(); // Qt reports touch point size as rectangles, but we will pretend it is an oval. - QRect touchRect = point.rect().toAlignedRect(); - if (touchRect.isValid()) { - m_radiusX = point.rect().width() / 2; - m_radiusY = point.rect().height() / 2; + QSizeF diameter = point.ellipseDiameters(); + if (diameter.isValid()) { + m_radiusX = diameter.width() / 2; + m_radiusY = diameter.height() / 2; } else { // http://www.w3.org/TR/2011/WD-touch-events-20110505: 1 if no value is known. m_radiusX = 1; @@ -259,7 +259,7 @@ WebKitPlatformGestureEvent::WebKitPlatformGestureEvent(QGestureEventFacade* even m_type = toPlatformEventType(event->type); m_globalPosition = event->globalPos; m_position = event->pos; - m_timestamp = WTF::currentTime(); + m_timestamp = WallTime::now(); } #endif diff --git a/Source/cmake/WebKitMacros.cmake b/Source/cmake/WebKitMacros.cmake index 120814b04c408..3b5bd80d5c80c 100644 --- a/Source/cmake/WebKitMacros.cmake +++ b/Source/cmake/WebKitMacros.cmake @@ -380,7 +380,9 @@ macro(WEBKIT_EXECUTABLE _target) else () set(_processor_architecture "*") endif () - target_link_options(${_target} PRIVATE "/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='${_processor_architecture}' publicKeyToken='6595b64144ccf1df' language='*'") + if(MSVC) + target_link_options(${_target} PRIVATE "/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='${_processor_architecture}' publicKeyToken='6595b64144ccf1df' language='*'") + endif() endif () endmacro() diff --git a/win-terminal.sh b/win-terminal.sh new file mode 100755 index 0000000000000..c00ebc1228e8b --- /dev/null +++ b/win-terminal.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +WINEPREFIX="/home/andy/PlayOnLinux's virtual drives/Qt_6.5.3_Win" WINEDEBUG=fixme-all /home/andy/.PlayOnLinux/wine/linux-amd64/6.17-staging/bin/wine64 cmd diff --git a/win_environment.reg b/win_environment.reg new file mode 100644 index 0000000000000..ae81c87923d4b Binary files /dev/null and b/win_environment.reg differ