mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-06-20 07:18:34 +00:00
049b3235ac
- Bug 1207494 - Part 8: Remove use of expression closure from dom/identity/. r=ferjm (34fac889f8) - minor crash thing (13fe2827c2) - Bug 1243359 - initialize mScrollSeriesNumber in all ScrollWheelInput constructors. r=roc (94163d8eca) - fix misspatch (b380a7bbe4) - Bug 1207412 - Make SystemTimeConverter use TimeStamp::Now() when converting times; r=karlt (f408549605) - Bug 1212102 - Drop unnecessary assertion comparing timestamps in SystemTimeConverter; r=karlt (1efaa04b3f) - Bug 1241302 - Slightly modernize this code. r=jst (c1e97bc069) - bug 1216916 clean up when InvokeDragSessionWithImage/Selection() fails r=roc (9cdf71b717) - Bug 1231329 - run ConvertToUnscaledDevPixels if *aPresContext is valid. r=roc (d10f23633b) - Bug 1245927: Innerize before creating DOM files from the file picker. r=baku (8754128362) - Bug 1155214 - Mark nsIBidiKeyboard as builtinclass; r=mrbkap (2d00326d2b) - reorder (c3c1ba92c9) - Bug 1236566 - add override declarations for widget/windows/GfxInfo.h; r=roc (940b40ed91) - Bug 1242659: Part 1. More information on the mismatches. r=jrmuizel (78331ddad2) - Block some Radeon drivers that crash on D3D9. (bug 1213107, r=jrmuizel) (482b66d313) - Bug 1203199 - Blacklist DXVA on some older intel drivers for causing crashes. r=jrmuizel (f1827d4498) - Bug 1203199 - Fix driver range with blacklist to avoid blacklisting other OSes. (2c2d547296) - Bug 1203199 - Bustage fix. CLOSED TREE (3233d407f3) - Bug 1178385. Enable DXVA on the G45 r=ajones (3c59a58a15) - Bug 1188442 IMMHandler::GetSelection() should use static Selection instance when IME doesn't have focus and return its or mSelection's reference r=emk (5cc4b30433) - Bug 1238899 Create hidden native caret for ATOK at composing in windowless plugin r=m_kato (40ef5bb4aa) - Bug 1257919 part 1. Kill off nsIXSLTException. r=khuey (11f37643f2) - Bug 1242072 - Change implementation of BaseProxyHandler::get() to follow ES6 [[Get]] specification. r=jorendorff (094a67f284) - Bug 489636 - Add a GC u-bench test for property tree splitting via deletion; r=sfink (9282fec25f) - Bug 1257919 part 2. Make nsIException and nsIStackFrame builtinclass, so we can start using [implicit_jscontext] on them. r=khuey (0e65fb8554) - Bug 1257919 part 3. Make the various toString methods on exceptions take an explicit JSContext. r=khuey (b342fb4930) - Bug 1257919 part 4. Stop returning StackFrame instances from exceptions::CreateStack. C++ callers of GetCurrentJSStack or exceptions::CreateStack always check for null anyway, and none of them seem to want this non-JS thing. r=khuey (d34036ccf9) - Bug 1257919 part 5. Get rid of the now-unused StackFrame class. r=khuey (aa13af0dfe) - Bug 1141222 - Create ScriptError with stack from Cu.reportError. r=bholley (b83ad26aa0) - Bug 1208641 - Extract stack from DOM/XPC exception. r=bholley (e382b5f48c) - Bug 1254380 part 1. Find the relevant window when the compartment we've got is an addon sandbox compartment in AutoJSAPI exception/warning reporting code. r=bholley (4b1f6c64a9) - Bug 1250630 - remove PBackgroundTest and ifdef ENABLE_TEST blocks. r=khuey (d7b36860a3) - Bug 1250963 part 1. Change NotifyRunnable::Dispatch to not require a JSContext. r=khuey (48e03c2fc2) - Bug 1250963 part 2. Remove the unused JSContext argument of WorkerPrivate::ModifyBusyCount. r=khuey (0f5ca42be1) - Bug 1250291 part 1. Stop pretending to report exceptions in MainThreadStopSyncLoopRunnable::PostDispatch. r=khuey (6e1c81cc06) - Bug 1250291 part 2. Stop pretending to report exceptions in MainThreadWorkerSyncRunnable::PostDispatch. r=khuey (f3d846ea31) - Bug 1250291 part 3. Stop pretending to report exceptions in WorkerDebuggerRunnable::PostDispatch. r=khuey (10bc1710d1) - Bug 1250975. Stop passing a JSContext argument to WorkerRunnable::PreDispatch and its overrides. r=khuey (71ab9046f0) - Bug 1255298. Just pass through the JSContext when passing through the NotificationOptions in notification code. r=wchen (552ae8e33e) - Bug 1250185 part 2. Remove some JSContext stuff that's no longer needed in Notification code. r=khuey (20b99ef28b) - Bug 1251045 part 8. Remove the JSContext argument from some nsINotificationStorageCallback methods. r=khuey (170c4afabc) - Bug 1227015 P7 Supress unused ErrorResult exception if the worker runnable failed to dispatch. r=catalinb (23a3cc6f45) - Bug 1251045 part 3. Remove the JSContext argument of WorkerRunnable::PostDispatch and its overrides. r=khuey (6a666d1a4a) - Bug 1251045 part 2. Remove the JSContext argument of ModifyBusyCountFromWorker. r=khuey (105bc4f59e) - Bug 1252130. Remove unnecessary JSContext argument from NotificationWorkerRunnable::WorkerRunInternal. r=khuey (642727f6f6) - Bug 1252127. Remove unnecessary JSContext argument from PromiseWorkerProxy::CleanUp. r=khuey (339e1157d1) - Bug 1251045 part 1. Make it possible to dispatch a ModifyBusyCountRunnable without a JSContext. r=khuey (665c1f81b4) - Bug 1251045 part 4. Remove the JSContext argument of WorkerRunnable::Dispatch. r=khuey (6c5cdab2b7) - Bug 1250185 part 1. nsIStructuredCloneContainer.initFromBase64 doesn't need a JSContext argument. r=khuey (d63a219209) - fix (773c0393aa) - Bug 1251045 part 5. Remove the JSContext argument from WorkerPrivateParent::Freeze/Thaw. r=khuey (cd419bfd2c) - Bug 1251045 part 6. Remove the JSContext argument from some worker debugger methods that no longer need it. r=khuey (abcc437cb9) - Bug 1251045 part 7. Remove the JSContext argument from some worker methods that no longer need it. r=khuey (3ddcbca08c) - Bug 1249652 part 1. Add a method on ErrorResult to steal an exception, if any, from a JSContext. r=khuey (9c07f5044b) - Bug 1229071 - importScripts should throw the correct error result in case the loading of one of scripts fails, r=bz (cd37645d76) - Bug 1229970 Abort script loading start requests if a load has been canceled. r=khuey (a44d9128ca) - Bug 1233171 Cancel channel when ScriptLoader is aborted during service worker script load. r=khuey (3b6ceafec7) - Bug 1249351 part 1. When doing importScripts of multiple scripts in a service worker, make sure to track the cache streams per-loadinfo, instead of trying to make them all wait on the same stream. r=bkelly (e1ccea9685) - Bug 1157544 - Fix a typo in the test; r=baku (8c0bf8f504) - Bug 1249351 part 2. Clean up test_importscript.html and add multiple-url importScript() case. r=bz (52b0a31032) - Bug 1249652 part 2. ScriptExecutorRunnable::WorkerRun should immediately move JS exceptions to its ErrorResult instead of allowing them to linger on the JSContext. r=baku,khuey (f628d3c8ba) - Bug 1249652 part 3. Simplify way we handle canceling when ScriptLoaderRunnable::RunInternal fails by canceling things with its actual failure code, so we don't have to guess which failed loads are actual failures and which are just canceled via this mechanism. r=baku,khuey (388543fbc3) - Bug 1251369. Use an AutoJSAPI that reports its own exceptions around the main runloop in workers. r=khuey (28b33287cd) - Bug 1251518. Fix js::ErrorReportToString to make a bit more sense, and change worker code to not use it anyway, so it matches the mainthread code. r=bholley,terrence (a48a40de90) - Bug 1254380 part 2. Go ahead and log the stack from our exception in AutoJSAPI::ReportException even if we don't have a window. r=bholley (64532b6017) - Bug 1212328 - Clean up some JSErrorReport-related code. r=Waldo,bz (d5aa611edc) - Bug 1255192 part 1. Remove the JSContext argument of JS::ExceptionStackOrNull. r=bholley (39b631d5ad) - bug 1252687 - make the ctor for CycleCollectorStats constexpr r=mccr8 (9e8168d8ac) - Bug 1254380 part 3. Skip firing error events for mainthread out of memory exceptions via AutoJSAPI::ReportException. r=bholley (d5e4e7dc29) - Bug 1254230 kinda-fix. Make sure to never send script errors with stacks attached to the console service if the associated windows have already had FreeInnerObjects called on them. r=bholley (8c379fe0e0) - Bug 1255192 part 2. Clean up the JSContext usage around xpc::FindExceptionStackForConsoleReport now that it just needs a JSContext for rooting. r=bholley (cade862491) - Bug 1255201. Improve the stack handling in nsXPCComponents_Utils::ReportError for the DOMException case to include the stack from the DOMException. r=bholley (fc6c065284) - Bug 1257919 part 6. Make the filename getter on JSStackFrame take an explicit JSContext. r=khuey (cde115b789) - Bug 1257919 part 7. Make the name getter on JSStackFrame take an explicit JSContext. r=khuey (d7466e9eab) - Bug 1257919 part 8. Make the line/column number getters on JSStackFrame take an explicit JSContext. r=khuey (b8766b98b2) - Bug 1257919 part 9. Make the asyncCause/asyncCaller getters on JSStackFrame take an explicit JSContext. r=khuey (b776ff9c6d) - Bug 1257919 part 10. Make the caller and formattedStack getters on JSStackFrame take an explicit JSContext. r=khuey (dc4d3d9091) - Bug 1252091. Add/RemoveFeature don't need a JSContext argument. r=khuey (5be6253a67) - Bug 1252123. Remove some unnecessary JSContext arguments from worker ScriptLoader methods. r=khuey (1657a35268) - Bug 1255181. Remove AutoJSAPI::InitWithLegacyErrorReporting. r=bholley (5ee7ac506e) - Bug 1254847 part 1. Take ownership of error reporting on the AutoEntryScript in nsXPCWrappedJSClass::DelegatedQueryInterface. r=bholley (62d987b030) - make style wrong again.... (fa4e6cfbc1) - Bug 1254847 part 2. Change nsJSNPRuntime to always use AutoEntryScript and always take ownership of error reporting. r=bholley (d24cb80622) - Bug 1251655 - Remove support for JavaScript-global-constructor-prototype-alias. r=bz. (2b354ea423) - Bug 1251655 - Remove support for JavaScript-DOM-class and JavaScript-DOM-interface. r=bz. (dd6786ea57) - Bug 1251275. Switch to using an AutoEntryScript in WorkerPrivate::RunExpiredTimeouts. r=khuey (f10d1b0dec) - Bug 1072144 part 1. Just release-assert that Promise::Resolve does not fail in service worker code. It can only do that on OOM or overrecursion anyway, and overrecursion is not likely if we're coming right off a runnable. r=khuey (ba4c89a3bc) - Bug 1072144 part 2. When UnregisterWorker tries to ScheduleWorker and that throws, just suppress the exception: there is no good place to report it anyway. r=khuey (ca563ec5cd) - Bug 1072144 part 3. Hoist the exception reporting out of WorkerRunnable::PostRun into WorkerRunnable::Run and make it unconditional. r=khuey (9914acd4a6) - Bug 1252221. When GetOrCreateGlobalScope fails while trying to run a ScriptExecutorRunnable::WorkerRun, just suppress the exception, because there is no way to report it without a compartment to work with. r=khuey (abcc9df148) - Bug 1072144 part 4. Add a WorkerRunnable::PreRun so that we can move worker global creation to it and always have an AutoEntryScript by the time we're evaluating the main worker script. r=khuey (007b528868) - Bug 1251276 part 1. Change WorkerPrivate::CancelAllTimeouts to no longer call RunExpiredTimeouts. r=khuey (6b937370a1) - Bug 1251276 part 2. Remove the JSContext argument of WorkerPrivate::CancelAllTimeouts. r=khuey (336b788e03) - Bug 1251380. Change things so that WorkerPrivate::NotifyInternal (hopefully) never throws. r=khuey (1d4863f83a) - Bug 1254846. Add an AutoEntryScript constructor that takes a JSObject instead of an nsIGlobalObject, for convenience. r=bholley (693857f9b0) - Bug 1255706 part 1. Remove JSContext argument from WorkerPrivate constructor. r=khuey (0486bdb01c) - Bug 1255706 part 2. Remove JSContext argument from WorkerPrivate::Terminate. r=khuey (f0b62de092) - Bug 1257568. Remove the JSContext argument of WorkerPrivate::Kill. r=khuey (ebe7d247b5) - Bug 1252189. Remove the unnecessary JSContext argument from WorkerPrivate::FreezeInternal/ThawInternal. r=khuey (22b137b05e) - Bug 1119490 - Expose the URL constructor to WorkerDebuggerGlobalScope;r=khuey (6f4fc13e1e) - Bug 1241841 - Clear the worker's debugger event queue before destroying its context;r=khuey (a1e8dd4b2d) - Bug 1249950 - Add Performance Markers for MessagePort - patch 1 - remove non-useful 'explicit', r=smaug (8a014b53e6) - Bug 1249950 - Add Performance Markers for MessagePort - patch 2, r=smaug, r=vporof (560caf0ae1) - bug 1250486 - make the ComponentsSH ctor constexpr r=bz (1c441dbb0f) - Bug 1257032: Make files in dom/workers actually build without unification. r=baku (6ab4ae0b65) - Bug 1241522 - handle OOM in nsExpatDriver::HandleCharacterData; r=hsivonen (b652220cdc) - Bug 1219482: Replace PRLogModuleInfo with LazyLogModule in various files.r=benjamin (5fd5e8dbc8) - Bug 1238545 - Remove nsISimpleUnicharStreamFactory; r=froydnj (f0018c5b16) - Bug 1257335. Replace some AutoSafeJSContext uses with AutoJSAPI or AutoJSContext uses. r=bholley (7baf79deb7) - Bug 1247635 - Unify PostMessageRunnable and DispatchEventRunnable in MessagePort.cpp, r=smaug (df2765c215) - Bug 1250572 - Force a parent object in MessagePort/Channel and in StructuredCloneHolder, r=smaug (2a929d59d1) - Bug 1255375 - MessagePort should not leak if DispatchMessage() fails, r=smaug (0a5cdebfb0) - Bug 1251272. Remove the dead code in ReportErrorRunnable::ReportError that could fail, and make it infallible. r=khuey (89e80694d0) - Bug 1072144 part 5. Stop fiddling with compartments on the JSContext before calling PostRun in WorkerRunnable::Run. Add some documentation explaining what's going on. r=khuey (91f4bb6a7c) - Bug 1072144 part 6. Switch WorkerRunnable::Run to calling TakeOwnershipOfErrorReporting on its AutoJSAPI/AutoEntryScript and remove the remaining JS_ReportPendingException callers in worker code. r=khuey (405d9e0282) - Bug 1179548 - Close the windows opened in private browsing worker tests; r=baku (acf3430b69) - Bug 1179753 - Use pushPrefEnv more in worker tests; r=baku (4bfd949c72) - Bug 1134224 - More test for test_bug1132395.html, r=ehsan (626eb100cd) - Bug 1134224 - onerror for test_bug1132395.html, r=ehsan (147195f57e) - Bug 1207635 - get rid of dom.workers.sharedWorkers.enabled pref, r=khuey (22fe2965c6) - Bug 1252592. JS warnings should not trigger error events on shared workers. r=khuey (7f05c2c00d) - Bug 1251308; r=luke (3cbec95738) - Bug 1246838 - Handle const qualifiers and references better in Variant. r=waldo (30da6e3ebf) - Bug 1254565 - Allow passing matchers as rvalues to Variant::match. r=froydnj (1dd799fb0a) - Bug 1246841 - Allow construction of Variant values using type inference. r=waldo (6ba3e6704c) - Bug 1250666 - Forward Variant's move constructor argument correctly to the underlying variant type. r=waldo (7353a53bf0) - Bug 1252185. Remove the dead "target" variable from CloseEventRunnable::WorkerRun. r=khuey (be172da10b) - Bug 1253059: Use fallible allocation in the worker error reporter. r=baku (963222bdd4) - Bug 1253199 - MessagePort should handle the dispatching a message when the parent window is gone, r=smaug (d552e3cd9e) - Bug 1252839 - Remove some if stmt after allocation with 'new' - patch 2, r=bz (3c7eb959bc) - Bug 1252839 - Remove some if stmt after allocation with 'new' - patch 1, r=bz (85067dbfb6) - Bug 1254855. Switch AutoEntryScripts in nsDirectoryViewer to take ownership of error reporting. r=bholley (8c10532323) - Bug 1252565 part 1. Push the script environment preparer bits up from XPCJSRuntime to CycleCollectedJSRuntime, because we need them on workers to do ctypes on workers properly. r=bholley (aecf2595dd) - Bug 1252565 part 2. Make dom::WarningOnlyErrorReporter handle workers. r=bholley (f415b8868b) - Bug 1244222 - Check for function interfaces in DelegatedQueryInterface. r=bz (d213eec83c) - Bug 1254393. Take ownership of error reporting on the AutoEntryScript in nsXPCWrappedJSClass::CallMethod. r=bholley (4765b501c0) - Bug 1251769 - Remove remaining references to MOZILLA_XPCOMRT_API from mfbt. r=froydnj (236adc1d4c) - Bug 1247835 (part 0) - Minor comment and style tweaks in BinarySearch.h. r=luke. (db04793721) - Bug 1244074 - Part 1: Move SheetParsingMode to a separate file. r=dholbert (290adaadea) - Bug 1244074 - Part 2: Add HandleRefPtr for refcounting StyleSheetHandles. r=dholbert r=waldo (8549b24392) - Bug 1244068 - Part 1: Add enum to represent the style system backend type. r=dholbert (c2e53feaf2) - Bug 1244068 - Part 2: Add skeleton ServoStyleSet and a StyleSetHandle smart pointer. r=dholbert (71a5c28629) - Bug 1244068 - Part 3: Factor out nsStyleSet getting in RestyleManager/ElementRestyler. r=dholbert (9e9f4f2e80) - Bug 1245406: In ReflowBlockFrame, use Maybe<> to destroy & reconstruct a stack-allocated object, instead of an explicit call to destructor & placement 'new'. r=dbaron (d36858b818) - Bug 1244068 - Part 4: Use StyleSetHandle instead of concrete style set class in most places. r=dholbert (93f9bcf799) - Bug 1244074 - Part 3: Add skeleton ServoStyleSheet and a StyleSheetHandle smart pointer. r=dholbert (5b4fbdce38) - Bug 1195173 - Apply CSP to preloaded styles within layout/style/Loader.cpp (r=bz) (d1ba920fd3) - Bug 1245681 - Fix addOverrideStyleSheet. r=bz (64099eac73) - Bug 1244074 - Part 4: Use StyleSheetHandle instead of concrete style sheet class in most places. r=dholberti (867470ac83) - Bug 1246013 (part 1) - Store a copy of the ETLDEntry directly in DomainEntry instead of a pointer to it. r=jduell. (587b3a9fb7) - Bug 1246013 (part 2) - Change "explicit/xpcom/effective-TLD-service" path to the more sensible "explicit/network/effective-TLD-service". r=jduell. (2e0df6f28f) - Bug 1247835 (part 1) - Use binary search instead of a hash table in nsEffectiveTLDService. r=jduell. (685dae01c0) - Bug 1257121 part 1 - Use struct for passing some params of font metrics. r=jfkthame (1dfd7a7429) - Bug 1257121 part 2 - Merge nsFontMetrics::Init to the constructor and remove unused failure handling code. r=jfkthame (0cdc441511) - Bug 1257121 part 3 - Add GetInflatedFontMetricsForFrame function to simplify a common use pattern. r=jfkthame (d9630ebd1b) - Bug 1257121 part 4 - Use return value rather than out param to retur font metrics. r=jfkthame (c9a5b1d1dd) - Bug 1257121 part 5 - Make nsDeviceContext::mFontCache a RefPtr. r=jfkthame (9c53238a6a)
802 lines
27 KiB
C++
802 lines
27 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "MathMLTextRunFactory.h"
|
|
|
|
#include "mozilla/ArrayUtils.h"
|
|
#include "mozilla/BinarySearch.h"
|
|
|
|
#include "nsStyleConsts.h"
|
|
#include "nsTextFrameUtils.h"
|
|
#include "nsFontMetrics.h"
|
|
#include "nsDeviceContext.h"
|
|
#include "nsUnicodeScriptCodes.h"
|
|
|
|
using namespace mozilla;
|
|
|
|
/*
|
|
Entries for the mathvariant lookup tables. mKey represents the Unicode
|
|
character to be transformed and is used for searching the tables.
|
|
mReplacement represents the mapped mathvariant Unicode character.
|
|
*/
|
|
typedef struct
|
|
{
|
|
uint32_t mKey;
|
|
uint32_t mReplacement;
|
|
} MathVarMapping;
|
|
|
|
/*
|
|
Lookup tables for use with mathvariant mappings to transform a unicode
|
|
character point to another unicode character that indicates the proper output.
|
|
mKey represents one of two concepts.
|
|
1. In the Latin table it represents a hole in the mathematical alphanumeric
|
|
block, where the character that should occupy that position is located
|
|
elsewhere.
|
|
2. It represents an Arabic letter.
|
|
|
|
As a replacement, 0 is reserved to indicate no mapping was found.
|
|
*/
|
|
static const MathVarMapping gArabicInitialMapTable[] = {
|
|
{ 0x628, 0x1EE21 },
|
|
{ 0x62A, 0x1EE35 },
|
|
{ 0x62B, 0x1EE36 },
|
|
{ 0x62C, 0x1EE22 },
|
|
{ 0x62D, 0x1EE27 },
|
|
{ 0x62E, 0x1EE37 },
|
|
{ 0x633, 0x1EE2E },
|
|
{ 0x634, 0x1EE34 },
|
|
{ 0x635, 0x1EE31 },
|
|
{ 0x636, 0x1EE39 },
|
|
{ 0x639, 0x1EE2F },
|
|
{ 0x63A, 0x1EE3B },
|
|
{ 0x641, 0x1EE30 },
|
|
{ 0x642, 0x1EE32 },
|
|
{ 0x643, 0x1EE2A },
|
|
{ 0x644, 0x1EE2B },
|
|
{ 0x645, 0x1EE2C },
|
|
{ 0x646, 0x1EE2D },
|
|
{ 0x647, 0x1EE24 },
|
|
{ 0x64A, 0x1EE29 }
|
|
};
|
|
|
|
static const MathVarMapping gArabicTailedMapTable[] = {
|
|
{ 0x62C, 0x1EE42 },
|
|
{ 0x62D, 0x1EE47 },
|
|
{ 0x62E, 0x1EE57 },
|
|
{ 0x633, 0x1EE4E },
|
|
{ 0x634, 0x1EE54 },
|
|
{ 0x635, 0x1EE51 },
|
|
{ 0x636, 0x1EE59 },
|
|
{ 0x639, 0x1EE4F },
|
|
{ 0x63A, 0x1EE5B },
|
|
{ 0x642, 0x1EE52 },
|
|
{ 0x644, 0x1EE4B },
|
|
{ 0x646, 0x1EE4D },
|
|
{ 0x64A, 0x1EE49 },
|
|
{ 0x66F, 0x1EE5F },
|
|
{ 0x6BA, 0x1EE5D }
|
|
};
|
|
|
|
static const MathVarMapping gArabicStretchedMapTable[] = {
|
|
{ 0x628, 0x1EE61 },
|
|
{ 0x62A, 0x1EE75 },
|
|
{ 0x62B, 0x1EE76 },
|
|
{ 0x62C, 0x1EE62 },
|
|
{ 0x62D, 0x1EE67 },
|
|
{ 0x62E, 0x1EE77 },
|
|
{ 0x633, 0x1EE6E },
|
|
{ 0x634, 0x1EE74 },
|
|
{ 0x635, 0x1EE71 },
|
|
{ 0x636, 0x1EE79 },
|
|
{ 0x637, 0x1EE68 },
|
|
{ 0x638, 0x1EE7A },
|
|
{ 0x639, 0x1EE6F },
|
|
{ 0x63A, 0x1EE7B },
|
|
{ 0x641, 0x1EE70 },
|
|
{ 0x642, 0x1EE72 },
|
|
{ 0x643, 0x1EE6A },
|
|
{ 0x645, 0x1EE6C },
|
|
{ 0x646, 0x1EE6D },
|
|
{ 0x647, 0x1EE64 },
|
|
{ 0x64A, 0x1EE69 },
|
|
{ 0x66E, 0x1EE7C },
|
|
{ 0x6A1, 0x1EE7E }
|
|
};
|
|
|
|
static const MathVarMapping gArabicLoopedMapTable[] = {
|
|
{ 0x627, 0x1EE80 },
|
|
{ 0x628, 0x1EE81 },
|
|
{ 0x62A, 0x1EE95 },
|
|
{ 0x62B, 0x1EE96 },
|
|
{ 0x62C, 0x1EE82 },
|
|
{ 0x62D, 0x1EE87 },
|
|
{ 0x62E, 0x1EE97 },
|
|
{ 0x62F, 0x1EE83 },
|
|
{ 0x630, 0x1EE98 },
|
|
{ 0x631, 0x1EE93 },
|
|
{ 0x632, 0x1EE86 },
|
|
{ 0x633, 0x1EE8E },
|
|
{ 0x634, 0x1EE94 },
|
|
{ 0x635, 0x1EE91 },
|
|
{ 0x636, 0x1EE99 },
|
|
{ 0x637, 0x1EE88 },
|
|
{ 0x638, 0x1EE9A },
|
|
{ 0x639, 0x1EE8F },
|
|
{ 0x63A, 0x1EE9B },
|
|
{ 0x641, 0x1EE90 },
|
|
{ 0x642, 0x1EE92 },
|
|
{ 0x644, 0x1EE8B },
|
|
{ 0x645, 0x1EE8C },
|
|
{ 0x646, 0x1EE8D },
|
|
{ 0x647, 0x1EE84 },
|
|
{ 0x648, 0x1EE85 },
|
|
{ 0x64A, 0x1EE89 }
|
|
};
|
|
|
|
static const MathVarMapping gArabicDoubleMapTable[] = {
|
|
{ 0x628, 0x1EEA1 },
|
|
{ 0x62A, 0x1EEB5 },
|
|
{ 0x62B, 0x1EEB6 },
|
|
{ 0x62C, 0x1EEA2 },
|
|
{ 0x62D, 0x1EEA7 },
|
|
{ 0x62E, 0x1EEB7 },
|
|
{ 0x62F, 0x1EEA3 },
|
|
{ 0x630, 0x1EEB8 },
|
|
{ 0x631, 0x1EEB3 },
|
|
{ 0x632, 0x1EEA6 },
|
|
{ 0x633, 0x1EEAE },
|
|
{ 0x634, 0x1EEB4 },
|
|
{ 0x635, 0x1EEB1 },
|
|
{ 0x636, 0x1EEB9 },
|
|
{ 0x637, 0x1EEA8 },
|
|
{ 0x638, 0x1EEBA },
|
|
{ 0x639, 0x1EEAF },
|
|
{ 0x63A, 0x1EEBB },
|
|
{ 0x641, 0x1EEB0 },
|
|
{ 0x642, 0x1EEB2 },
|
|
{ 0x644, 0x1EEAB },
|
|
{ 0x645, 0x1EEAC },
|
|
{ 0x646, 0x1EEAD },
|
|
{ 0x648, 0x1EEA5 },
|
|
{ 0x64A, 0x1EEA9 }
|
|
};
|
|
|
|
static const MathVarMapping gLatinExceptionMapTable[] = {
|
|
{ 0x1D455, 0x210E },
|
|
{ 0x1D49D, 0x212C },
|
|
{ 0x1D4A0, 0x2130 },
|
|
{ 0x1D4A1, 0x2131 },
|
|
{ 0x1D4A3, 0x210B },
|
|
{ 0x1D4A4, 0x2110 },
|
|
{ 0x1D4A7, 0x2112 },
|
|
{ 0x1D4A8, 0x2133 },
|
|
{ 0x1D4AD, 0x211B },
|
|
{ 0x1D4BA, 0x212F },
|
|
{ 0x1D4BC, 0x210A },
|
|
{ 0x1D4C4, 0x2134 },
|
|
{ 0x1D506, 0x212D },
|
|
{ 0x1D50B, 0x210C },
|
|
{ 0x1D50C, 0x2111 },
|
|
{ 0x1D515, 0x211C },
|
|
{ 0x1D51D, 0x2128 },
|
|
{ 0x1D53A, 0x2102 },
|
|
{ 0x1D53F, 0x210D },
|
|
{ 0x1D545, 0x2115 },
|
|
{ 0x1D547, 0x2119 },
|
|
{ 0x1D548, 0x211A },
|
|
{ 0x1D549, 0x211D },
|
|
{ 0x1D551, 0x2124 }
|
|
};
|
|
|
|
namespace {
|
|
|
|
struct MathVarMappingWrapper
|
|
{
|
|
const MathVarMapping* const mTable;
|
|
explicit MathVarMappingWrapper(const MathVarMapping* aTable) : mTable(aTable) {}
|
|
uint32_t operator[](size_t index) const {
|
|
return mTable[index].mKey;
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
// Finds a MathVarMapping struct with the specified key (aKey) within aTable.
|
|
// aTable must be an array, whose length is specified by aNumElements
|
|
static uint32_t
|
|
MathvarMappingSearch(uint32_t aKey, const MathVarMapping* aTable, uint32_t aNumElements)
|
|
{
|
|
size_t index;
|
|
if (BinarySearch(MathVarMappingWrapper(aTable), 0, aNumElements, aKey, &index)) {
|
|
return aTable[index].mReplacement;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define GREEK_UPPER_THETA 0x03F4
|
|
#define HOLE_GREEK_UPPER_THETA 0x03A2
|
|
#define NABLA 0x2207
|
|
#define PARTIAL_DIFFERENTIAL 0x2202
|
|
#define GREEK_UPPER_ALPHA 0x0391
|
|
#define GREEK_UPPER_OMEGA 0x03A9
|
|
#define GREEK_LOWER_ALPHA 0x03B1
|
|
#define GREEK_LOWER_OMEGA 0x03C9
|
|
#define GREEK_LUNATE_EPSILON_SYMBOL 0x03F5
|
|
#define GREEK_THETA_SYMBOL 0x03D1
|
|
#define GREEK_KAPPA_SYMBOL 0x03F0
|
|
#define GREEK_PHI_SYMBOL 0x03D5
|
|
#define GREEK_RHO_SYMBOL 0x03F1
|
|
#define GREEK_PI_SYMBOL 0x03D6
|
|
#define GREEK_LETTER_DIGAMMA 0x03DC
|
|
#define GREEK_SMALL_LETTER_DIGAMMA 0x03DD
|
|
#define MATH_BOLD_CAPITAL_DIGAMMA 0x1D7CA
|
|
#define MATH_BOLD_SMALL_DIGAMMA 0x1D7CB
|
|
|
|
#define LATIN_SMALL_LETTER_DOTLESS_I 0x0131
|
|
#define LATIN_SMALL_LETTER_DOTLESS_J 0x0237
|
|
|
|
#define MATH_ITALIC_SMALL_DOTLESS_I 0x1D6A4
|
|
#define MATH_ITALIC_SMALL_DOTLESS_J 0x1D6A5
|
|
|
|
#define MATH_BOLD_UPPER_A 0x1D400
|
|
#define MATH_ITALIC_UPPER_A 0x1D434
|
|
#define MATH_BOLD_SMALL_A 0x1D41A
|
|
#define MATH_BOLD_UPPER_ALPHA 0x1D6A8
|
|
#define MATH_BOLD_SMALL_ALPHA 0x1D6C2
|
|
#define MATH_ITALIC_UPPER_ALPHA 0x1D6E2
|
|
#define MATH_BOLD_DIGIT_ZERO 0x1D7CE
|
|
#define MATH_DOUBLE_STRUCK_ZERO 0x1D7D8
|
|
|
|
#define MATH_BOLD_UPPER_THETA 0x1D6B9
|
|
#define MATH_BOLD_NABLA 0x1D6C1
|
|
#define MATH_BOLD_PARTIAL_DIFFERENTIAL 0x1D6DB
|
|
#define MATH_BOLD_EPSILON_SYMBOL 0x1D6DC
|
|
#define MATH_BOLD_THETA_SYMBOL 0x1D6DD
|
|
#define MATH_BOLD_KAPPA_SYMBOL 0x1D6DE
|
|
#define MATH_BOLD_PHI_SYMBOL 0x1D6DF
|
|
#define MATH_BOLD_RHO_SYMBOL 0x1D6E0
|
|
#define MATH_BOLD_PI_SYMBOL 0x1D6E1
|
|
|
|
/*
|
|
Performs the character mapping needed to implement MathML's mathvariant
|
|
attribute. It takes a unicode character and maps it to its appropriate
|
|
mathvariant counterpart specified by aMathVar. The mapped character is
|
|
typically located within Unicode's mathematical blocks (0x1D***, 0x1EE**) but
|
|
there are exceptions which this function accounts for.
|
|
Characters without a valid mapping or valid aMathvar value are returned
|
|
unaltered. Characters already in the mathematical blocks (or are one of the
|
|
exceptions) are never transformed.
|
|
Acceptable values for aMathVar are specified in layout/style/nsStyleConsts.h.
|
|
The transformable characters can be found at:
|
|
http://lists.w3.org/Archives/Public/www-math/2013Sep/0012.html and
|
|
https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols
|
|
*/
|
|
static uint32_t
|
|
MathVariant(uint32_t aCh, uint8_t aMathVar)
|
|
{
|
|
uint32_t baseChar;
|
|
enum CharacterType {
|
|
kIsLatin,
|
|
kIsGreekish,
|
|
kIsNumber,
|
|
kIsArabic,
|
|
};
|
|
CharacterType varType;
|
|
|
|
int8_t multiplier;
|
|
|
|
if (aMathVar <= NS_MATHML_MATHVARIANT_NORMAL) {
|
|
// nothing to do here
|
|
return aCh;
|
|
}
|
|
if (aMathVar > NS_MATHML_MATHVARIANT_STRETCHED) {
|
|
NS_ASSERTION(false, "Illegal mathvariant value");
|
|
return aCh;
|
|
}
|
|
|
|
// Exceptional characters with at most one possible transformation
|
|
if (aCh == HOLE_GREEK_UPPER_THETA) {
|
|
// Nothing at this code point is transformed
|
|
return aCh;
|
|
}
|
|
if (aCh == GREEK_LETTER_DIGAMMA) {
|
|
if (aMathVar == NS_MATHML_MATHVARIANT_BOLD) {
|
|
return MATH_BOLD_CAPITAL_DIGAMMA;
|
|
}
|
|
return aCh;
|
|
}
|
|
if (aCh == GREEK_SMALL_LETTER_DIGAMMA) {
|
|
if (aMathVar == NS_MATHML_MATHVARIANT_BOLD) {
|
|
return MATH_BOLD_SMALL_DIGAMMA;
|
|
}
|
|
return aCh;
|
|
}
|
|
if (aCh == LATIN_SMALL_LETTER_DOTLESS_I) {
|
|
if (aMathVar == NS_MATHML_MATHVARIANT_ITALIC) {
|
|
return MATH_ITALIC_SMALL_DOTLESS_I;
|
|
}
|
|
return aCh;
|
|
}
|
|
if (aCh == LATIN_SMALL_LETTER_DOTLESS_J) {
|
|
if (aMathVar == NS_MATHML_MATHVARIANT_ITALIC) {
|
|
return MATH_ITALIC_SMALL_DOTLESS_J;
|
|
}
|
|
return aCh;
|
|
}
|
|
|
|
// The Unicode mathematical blocks are divided into four segments: Latin,
|
|
// Greek, numbers and Arabic. In the case of the first three
|
|
// baseChar represents the relative order in which the characters are
|
|
// encoded in the Unicode mathematical block, normalised to the first
|
|
// character of that sequence.
|
|
//
|
|
if ('A' <= aCh && aCh <= 'Z') {
|
|
baseChar = aCh - 'A';
|
|
varType = kIsLatin;
|
|
} else if ('a' <= aCh && aCh <= 'z') {
|
|
// Lowercase characters are placed immediately after the uppercase
|
|
// characters in the Unicode mathematical block. The constant subtraction
|
|
// represents the number of characters between the start of the sequence
|
|
// (capital A) and the first lowercase letter.
|
|
baseChar = MATH_BOLD_SMALL_A-MATH_BOLD_UPPER_A + aCh - 'a';
|
|
varType = kIsLatin;
|
|
} else if ('0' <= aCh && aCh <= '9') {
|
|
baseChar = aCh - '0';
|
|
varType = kIsNumber;
|
|
} else if (GREEK_UPPER_ALPHA <= aCh && aCh <= GREEK_UPPER_OMEGA) {
|
|
baseChar = aCh-GREEK_UPPER_ALPHA;
|
|
varType = kIsGreekish;
|
|
} else if (GREEK_LOWER_ALPHA <= aCh && aCh <= GREEK_LOWER_OMEGA) {
|
|
// Lowercase Greek comes after uppercase Greek.
|
|
// Note in this instance the presence of an additional character (Nabla)
|
|
// between the end of the uppercase Greek characters and the lowercase
|
|
// ones.
|
|
baseChar = MATH_BOLD_SMALL_ALPHA - MATH_BOLD_UPPER_ALPHA
|
|
+ aCh-GREEK_LOWER_ALPHA;
|
|
varType = kIsGreekish;
|
|
} else if (0x0600 <= aCh && aCh <= 0x06FF) {
|
|
// Arabic characters are defined within this range
|
|
varType = kIsArabic;
|
|
} else {
|
|
switch (aCh) {
|
|
case GREEK_UPPER_THETA:
|
|
baseChar = MATH_BOLD_UPPER_THETA-MATH_BOLD_UPPER_ALPHA;
|
|
break;
|
|
case NABLA:
|
|
baseChar = MATH_BOLD_NABLA-MATH_BOLD_UPPER_ALPHA;
|
|
break;
|
|
case PARTIAL_DIFFERENTIAL:
|
|
baseChar = MATH_BOLD_PARTIAL_DIFFERENTIAL - MATH_BOLD_UPPER_ALPHA;
|
|
break;
|
|
case GREEK_LUNATE_EPSILON_SYMBOL:
|
|
baseChar = MATH_BOLD_EPSILON_SYMBOL - MATH_BOLD_UPPER_ALPHA;
|
|
break;
|
|
case GREEK_THETA_SYMBOL:
|
|
baseChar = MATH_BOLD_THETA_SYMBOL - MATH_BOLD_UPPER_ALPHA;
|
|
break;
|
|
case GREEK_KAPPA_SYMBOL:
|
|
baseChar = MATH_BOLD_KAPPA_SYMBOL - MATH_BOLD_UPPER_ALPHA;
|
|
break;
|
|
case GREEK_PHI_SYMBOL:
|
|
baseChar = MATH_BOLD_PHI_SYMBOL - MATH_BOLD_UPPER_ALPHA;
|
|
break;
|
|
case GREEK_RHO_SYMBOL:
|
|
baseChar = MATH_BOLD_RHO_SYMBOL - MATH_BOLD_UPPER_ALPHA;
|
|
break;
|
|
case GREEK_PI_SYMBOL:
|
|
baseChar = MATH_BOLD_PI_SYMBOL - MATH_BOLD_UPPER_ALPHA;
|
|
break;
|
|
default:
|
|
return aCh;
|
|
}
|
|
|
|
varType = kIsGreekish;
|
|
}
|
|
|
|
if (varType == kIsNumber) {
|
|
switch (aMathVar) {
|
|
// Each possible number mathvariant is encoded in a single, contiguous
|
|
// block. For example the beginning of the double struck number range
|
|
// follows immediately after the end of the bold number range.
|
|
// multiplier represents the order of the sequences relative to the first
|
|
// one.
|
|
case NS_MATHML_MATHVARIANT_BOLD:
|
|
multiplier = 0;
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_DOUBLE_STRUCK:
|
|
multiplier = 1;
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_SANS_SERIF:
|
|
multiplier = 2;
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_BOLD_SANS_SERIF:
|
|
multiplier = 3;
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_MONOSPACE:
|
|
multiplier = 4;
|
|
break;
|
|
default:
|
|
// This mathvariant isn't defined for numbers or is otherwise normal
|
|
return aCh;
|
|
}
|
|
// As the ranges are contiguous, to find the desired mathvariant range it
|
|
// is sufficient to multiply the position within the sequence order
|
|
// (multiplier) with the period of the sequence (which is constant for all
|
|
// number sequences) and to add the character point of the first character
|
|
// within the number mathvariant range.
|
|
// To this the baseChar calculated earlier is added to obtain the final
|
|
// code point.
|
|
return baseChar+multiplier*(MATH_DOUBLE_STRUCK_ZERO-MATH_BOLD_DIGIT_ZERO)
|
|
+MATH_BOLD_DIGIT_ZERO;
|
|
} else if (varType == kIsGreekish) {
|
|
switch (aMathVar) {
|
|
case NS_MATHML_MATHVARIANT_BOLD:
|
|
multiplier = 0;
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_ITALIC:
|
|
multiplier = 1;
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_BOLD_ITALIC:
|
|
multiplier = 2;
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_BOLD_SANS_SERIF:
|
|
multiplier = 3;
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_SANS_SERIF_BOLD_ITALIC:
|
|
multiplier = 4;
|
|
break;
|
|
default:
|
|
// This mathvariant isn't defined for Greek or is otherwise normal
|
|
return aCh;
|
|
}
|
|
// See the kIsNumber case for an explanation of the following calculation
|
|
return baseChar + MATH_BOLD_UPPER_ALPHA +
|
|
multiplier*(MATH_ITALIC_UPPER_ALPHA - MATH_BOLD_UPPER_ALPHA);
|
|
}
|
|
|
|
uint32_t tempChar;
|
|
uint32_t newChar;
|
|
if (varType == kIsArabic) {
|
|
const MathVarMapping* mapTable;
|
|
uint32_t tableLength;
|
|
switch (aMathVar) {
|
|
/* The Arabic mathematical block is not continuous, nor does it have a
|
|
* monotonic mapping to the unencoded characters, requiring the use of a
|
|
* lookup table.
|
|
*/
|
|
case NS_MATHML_MATHVARIANT_INITIAL:
|
|
mapTable = gArabicInitialMapTable;
|
|
tableLength = ArrayLength(gArabicInitialMapTable);
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_TAILED:
|
|
mapTable = gArabicTailedMapTable;
|
|
tableLength = ArrayLength(gArabicTailedMapTable);
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_STRETCHED:
|
|
mapTable = gArabicStretchedMapTable;
|
|
tableLength = ArrayLength(gArabicStretchedMapTable);
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_LOOPED:
|
|
mapTable = gArabicLoopedMapTable;
|
|
tableLength = ArrayLength(gArabicLoopedMapTable);
|
|
break;
|
|
case NS_MATHML_MATHVARIANT_DOUBLE_STRUCK:
|
|
mapTable = gArabicDoubleMapTable;
|
|
tableLength = ArrayLength(gArabicDoubleMapTable);
|
|
break;
|
|
default:
|
|
// No valid transformations exist
|
|
return aCh;
|
|
}
|
|
newChar = MathvarMappingSearch(aCh, mapTable, tableLength);
|
|
} else {
|
|
// Must be Latin
|
|
if (aMathVar > NS_MATHML_MATHVARIANT_MONOSPACE) {
|
|
// Latin doesn't support the Arabic mathvariants
|
|
return aCh;
|
|
}
|
|
multiplier = aMathVar - 2;
|
|
// This is possible because the values for NS_MATHML_MATHVARIANT_* are
|
|
// chosen to coincide with the order in which the encoded mathvariant
|
|
// characters are located within their unicode block (less an offset to
|
|
// avoid _NONE and _NORMAL variants)
|
|
// See the kIsNumber case for an explanation of the following calculation
|
|
tempChar = baseChar + MATH_BOLD_UPPER_A +
|
|
multiplier*(MATH_ITALIC_UPPER_A - MATH_BOLD_UPPER_A);
|
|
// There are roughly twenty characters that are located outside of the
|
|
// mathematical block, so the spaces where they ought to be are used
|
|
// as keys for a lookup table containing the correct character mappings.
|
|
newChar = MathvarMappingSearch(tempChar, gLatinExceptionMapTable,
|
|
ArrayLength(gLatinExceptionMapTable));
|
|
}
|
|
|
|
if (newChar) {
|
|
return newChar;
|
|
} else if (varType == kIsLatin) {
|
|
return tempChar;
|
|
} else {
|
|
// An Arabic character without a corresponding mapping
|
|
return aCh;
|
|
}
|
|
|
|
}
|
|
|
|
#define TT_SSTY TRUETYPE_TAG('s', 's', 't', 'y')
|
|
#define TT_DTLS TRUETYPE_TAG('d', 't', 'l', 's')
|
|
|
|
void
|
|
MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|
mozilla::gfx::DrawTarget* aRefDrawTarget,
|
|
gfxMissingFontRecorder* aMFR)
|
|
{
|
|
gfxFontGroup* fontGroup = aTextRun->GetFontGroup();
|
|
|
|
nsAutoString convertedString;
|
|
AutoTArray<bool,50> charsToMergeArray;
|
|
AutoTArray<bool,50> deletedCharsArray;
|
|
AutoTArray<RefPtr<nsTransformedCharStyle>,50> styleArray;
|
|
AutoTArray<uint8_t,50> canBreakBeforeArray;
|
|
bool mergeNeeded = false;
|
|
|
|
bool singleCharMI =
|
|
aTextRun->GetFlags() & nsTextFrameUtils::TEXT_IS_SINGLE_CHAR_MI;
|
|
|
|
uint32_t length = aTextRun->GetLength();
|
|
const char16_t* str = aTextRun->mString.BeginReading();
|
|
const nsTArray<RefPtr<nsTransformedCharStyle>>& styles = aTextRun->mStyles;
|
|
nsFont font;
|
|
if (length) {
|
|
font = styles[0]->mFont;
|
|
|
|
if (mSSTYScriptLevel || (mFlags & MATH_FONT_FEATURE_DTLS)) {
|
|
bool foundSSTY = false;
|
|
bool foundDTLS = false;
|
|
// We respect ssty settings explicitly set by the user
|
|
for (uint32_t i = 0; i < font.fontFeatureSettings.Length(); i++) {
|
|
if (font.fontFeatureSettings[i].mTag == TT_SSTY) {
|
|
foundSSTY = true;
|
|
} else if (font.fontFeatureSettings[i].mTag == TT_DTLS) {
|
|
foundDTLS = true;
|
|
}
|
|
}
|
|
if (mSSTYScriptLevel && !foundSSTY) {
|
|
uint8_t sstyLevel = 0;
|
|
float scriptScaling = pow(styles[0]->mScriptSizeMultiplier,
|
|
mSSTYScriptLevel);
|
|
static_assert(NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER < 1,
|
|
"Shouldn't it make things smaller?");
|
|
/*
|
|
An SSTY level of 2 is set if the scaling factor is less than or equal
|
|
to halfway between that for a scriptlevel of 1 (0.71) and that of a
|
|
scriptlevel of 2 (0.71^2), assuming the default script size multiplier.
|
|
An SSTY level of 1 is set if the script scaling factor is less than
|
|
or equal that for a scriptlevel of 1 assuming the default script size
|
|
multiplier.
|
|
|
|
User specified values of script size multiplier will change the scaling
|
|
factor which mSSTYScriptLevel values correspond to.
|
|
|
|
In the event that the script size multiplier actually makes things
|
|
larger, no change is made.
|
|
|
|
To opt out of this change, add the following to the stylesheet:
|
|
"font-feature-settings: 'ssty' 0"
|
|
*/
|
|
if (scriptScaling <= (NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER +
|
|
(NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER *
|
|
NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER))/2) {
|
|
// Currently only the first two ssty settings are used, so two is large
|
|
// as we go
|
|
sstyLevel = 2;
|
|
} else if (scriptScaling <= NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER) {
|
|
sstyLevel = 1;
|
|
}
|
|
if (sstyLevel) {
|
|
gfxFontFeature settingSSTY;
|
|
settingSSTY.mTag = TT_SSTY;
|
|
settingSSTY.mValue = sstyLevel;
|
|
font.fontFeatureSettings.AppendElement(settingSSTY);
|
|
}
|
|
}
|
|
/*
|
|
Apply the dtls font feature setting (dotless).
|
|
This gets applied to the base frame and all descendants of the base
|
|
frame of certain <mover> and <munderover> frames.
|
|
|
|
See nsMathMLmunderoverFrame.cpp for a full description.
|
|
|
|
To opt out of this change, add the following to the stylesheet:
|
|
"font-feature-settings: 'dtls' 0"
|
|
*/
|
|
if ((mFlags & MATH_FONT_FEATURE_DTLS) && !foundDTLS) {
|
|
gfxFontFeature settingDTLS;
|
|
settingDTLS.mTag = TT_DTLS;
|
|
settingDTLS.mValue = 1;
|
|
font.fontFeatureSettings.AppendElement(settingDTLS);
|
|
}
|
|
}
|
|
}
|
|
|
|
uint8_t mathVar = NS_MATHML_MATHVARIANT_NONE;
|
|
bool doMathvariantStyling = true;
|
|
|
|
for (uint32_t i = 0; i < length; ++i) {
|
|
int extraChars = 0;
|
|
mathVar = styles[i]->mMathVariant;
|
|
|
|
if (singleCharMI && mathVar == NS_MATHML_MATHVARIANT_NONE) {
|
|
// If the user has explicitly set a non-default value for fontstyle or
|
|
// fontweight, the italic mathvariant behaviour of <mi> is disabled
|
|
// This overrides the initial values specified in fontStyle, to avoid
|
|
// inconsistencies in which attributes allow CSS changes and which do not.
|
|
if (mFlags & MATH_FONT_WEIGHT_BOLD) {
|
|
font.weight = NS_FONT_WEIGHT_BOLD;
|
|
if (mFlags & MATH_FONT_STYLING_NORMAL) {
|
|
font.style = NS_FONT_STYLE_NORMAL;
|
|
} else {
|
|
font.style = NS_FONT_STYLE_ITALIC;
|
|
}
|
|
} else if (mFlags & MATH_FONT_STYLING_NORMAL) {
|
|
font.style = NS_FONT_STYLE_NORMAL;
|
|
font.weight = NS_FONT_WEIGHT_NORMAL;
|
|
} else {
|
|
mathVar = NS_MATHML_MATHVARIANT_ITALIC;
|
|
}
|
|
}
|
|
|
|
uint32_t ch = str[i];
|
|
if (NS_IS_HIGH_SURROGATE(ch) && i < length - 1 &&
|
|
NS_IS_LOW_SURROGATE(str[i + 1])) {
|
|
ch = SURROGATE_TO_UCS4(ch, str[i + 1]);
|
|
}
|
|
uint32_t ch2 = MathVariant(ch, mathVar);
|
|
|
|
if (mathVar == NS_MATHML_MATHVARIANT_BOLD ||
|
|
mathVar == NS_MATHML_MATHVARIANT_BOLD_ITALIC ||
|
|
mathVar == NS_MATHML_MATHVARIANT_ITALIC) {
|
|
if (ch == ch2 && ch != 0x20 && ch != 0xA0) {
|
|
// Don't apply the CSS style if a character cannot be
|
|
// transformed. There is an exception for whitespace as it is both
|
|
// common and innocuous.
|
|
doMathvariantStyling = false;
|
|
}
|
|
if (ch2 != ch) {
|
|
// Bug 930504. Some platforms do not have fonts for Mathematical
|
|
// Alphanumeric Symbols. Hence we check whether the transformed
|
|
// character is actually available.
|
|
uint8_t matchType;
|
|
RefPtr<gfxFont> mathFont = fontGroup->
|
|
FindFontForChar(ch2, 0, 0, HB_SCRIPT_COMMON, nullptr, &matchType);
|
|
if (mathFont) {
|
|
// Don't apply the CSS style if there is a math font for at least one
|
|
// of the transformed character in this text run.
|
|
doMathvariantStyling = false;
|
|
} else {
|
|
// We fallback to the original character.
|
|
ch2 = ch;
|
|
if (aMFR) {
|
|
aMFR->RecordScript(MOZ_SCRIPT_MATHEMATICAL_NOTATION);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
deletedCharsArray.AppendElement(false);
|
|
charsToMergeArray.AppendElement(false);
|
|
styleArray.AppendElement(styles[i]);
|
|
canBreakBeforeArray.AppendElement(aTextRun->CanBreakLineBefore(i));
|
|
|
|
if (IS_IN_BMP(ch2)) {
|
|
convertedString.Append(ch2);
|
|
} else {
|
|
convertedString.Append(H_SURROGATE(ch2));
|
|
convertedString.Append(L_SURROGATE(ch2));
|
|
++extraChars;
|
|
if (!IS_IN_BMP(ch)) {
|
|
deletedCharsArray.AppendElement(true); // not exactly deleted, but
|
|
// the trailing surrogate is skipped
|
|
++i;
|
|
}
|
|
}
|
|
|
|
while (extraChars-- > 0) {
|
|
mergeNeeded = true;
|
|
charsToMergeArray.AppendElement(true);
|
|
styleArray.AppendElement(styles[i]);
|
|
canBreakBeforeArray.AppendElement(false);
|
|
}
|
|
}
|
|
|
|
uint32_t flags;
|
|
gfxTextRunFactory::Parameters innerParams =
|
|
GetParametersForInner(aTextRun, &flags, aRefDrawTarget);
|
|
|
|
nsAutoPtr<nsTransformedTextRun> transformedChild;
|
|
nsAutoPtr<gfxTextRun> cachedChild;
|
|
gfxTextRun* child;
|
|
|
|
if (mathVar == NS_MATHML_MATHVARIANT_BOLD && doMathvariantStyling) {
|
|
font.style = NS_FONT_STYLE_NORMAL;
|
|
font.weight = NS_FONT_WEIGHT_BOLD;
|
|
} else if (mathVar == NS_MATHML_MATHVARIANT_ITALIC && doMathvariantStyling) {
|
|
font.style = NS_FONT_STYLE_ITALIC;
|
|
font.weight = NS_FONT_WEIGHT_NORMAL;
|
|
} else if (mathVar == NS_MATHML_MATHVARIANT_BOLD_ITALIC &&
|
|
doMathvariantStyling) {
|
|
font.style = NS_FONT_STYLE_ITALIC;
|
|
font.weight = NS_FONT_WEIGHT_BOLD;
|
|
} else if (mathVar != NS_MATHML_MATHVARIANT_NONE) {
|
|
// Mathvariant overrides fontstyle and fontweight
|
|
// Need to check to see if mathvariant is actually applied as this function
|
|
// is used for other purposes.
|
|
font.style = NS_FONT_STYLE_NORMAL;
|
|
font.weight = NS_FONT_WEIGHT_NORMAL;
|
|
}
|
|
gfxFontGroup* newFontGroup = nullptr;
|
|
|
|
// Get the correct gfxFontGroup that corresponds to the earlier font changes.
|
|
if (length) {
|
|
font.size = NSToCoordRound(font.size * mFontInflation);
|
|
nsPresContext* pc = styles[0]->mPresContext;
|
|
nsFontMetrics::Params params;
|
|
params.language = styles[0]->mLanguage;
|
|
params.explicitLanguage = styles[0]->mExplicitLanguage;
|
|
params.userFontSet = pc->GetUserFontSet();
|
|
params.textPerf = pc->GetTextPerfMetrics();
|
|
RefPtr<nsFontMetrics> metrics =
|
|
pc->DeviceContext()->GetMetricsFor(font, params);
|
|
newFontGroup = metrics->GetThebesFontGroup();
|
|
}
|
|
|
|
if (!newFontGroup) {
|
|
// If we can't get a new font group, fall back to the old one. Rendering
|
|
// will be incorrect, but not significantly so.
|
|
newFontGroup = fontGroup;
|
|
}
|
|
|
|
if (mInnerTransformingTextRunFactory) {
|
|
transformedChild = mInnerTransformingTextRunFactory->MakeTextRun(
|
|
convertedString.BeginReading(), convertedString.Length(),
|
|
&innerParams, newFontGroup, flags, Move(styleArray), false);
|
|
child = transformedChild.get();
|
|
} else {
|
|
cachedChild = newFontGroup->MakeTextRun(
|
|
convertedString.BeginReading(), convertedString.Length(),
|
|
&innerParams, flags, aMFR);
|
|
child = cachedChild.get();
|
|
}
|
|
if (!child)
|
|
return;
|
|
|
|
typedef gfxTextRun::Range Range;
|
|
|
|
// Copy potential linebreaks into child so they're preserved
|
|
// (and also child will be shaped appropriately)
|
|
NS_ASSERTION(convertedString.Length() == canBreakBeforeArray.Length(),
|
|
"Dropped characters or break-before values somewhere!");
|
|
Range range(0, uint32_t(canBreakBeforeArray.Length()));
|
|
child->SetPotentialLineBreaks(range, canBreakBeforeArray.Elements());
|
|
if (transformedChild) {
|
|
transformedChild->FinishSettingProperties(aRefDrawTarget, aMFR);
|
|
}
|
|
|
|
if (mergeNeeded) {
|
|
// Now merge multiple characters into one multi-glyph character as required
|
|
NS_ASSERTION(charsToMergeArray.Length() == child->GetLength(),
|
|
"source length mismatch");
|
|
NS_ASSERTION(deletedCharsArray.Length() == aTextRun->GetLength(),
|
|
"destination length mismatch");
|
|
MergeCharactersInTextRun(aTextRun, child, charsToMergeArray.Elements(),
|
|
deletedCharsArray.Elements());
|
|
} else {
|
|
// No merging to do, so just copy; this produces a more optimized textrun.
|
|
// We can't steal the data because the child may be cached and stealing
|
|
// the data would break the cache.
|
|
aTextRun->ResetGlyphRuns();
|
|
aTextRun->CopyGlyphDataFrom(child, Range(child), 0);
|
|
}
|
|
}
|