Files
palemoon27/layout/generic/MathMLTextRunFactory.cpp
T
roytam1 049b3235ac import changes from `dev' branch of rmottola/Arctic-Fox:
- 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)
2024-01-29 15:26:23 +08:00

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);
}
}