merge mozilla-central to autoland. r=merge a=merge

--HG--
extra : rebase_source : 819bdfcc5e3f50cb5a3d8d76ce1f88ceeb0dd5a9
This commit is contained in:
Sebastian Hengst 2017-10-17 23:54:52 +02:00
commit fea24c0daf
219 changed files with 4436 additions and 2993 deletions

View File

@ -109,7 +109,7 @@ tabbrowser {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser");
}
.tabbrowser-tabs {
#tabbrowser-tabs {
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabs");
}
@ -173,19 +173,19 @@ tabbrowser {
display: none;
}
.tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
#tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
position: fixed !important;
display: block; /* position:fixed already does this (bug 579776), but let's be explicit */
}
.tabbrowser-tabs[movingtab] > .tabbrowser-tab[selected] {
#tabbrowser-tabs[movingtab] > .tabbrowser-tab[selected] {
position: relative;
z-index: 2;
pointer-events: none; /* avoid blocking dragover events on scroll buttons */
}
.tabbrowser-tab[tabdrop-samewindow],
.tabbrowser-tabs[movingtab] > .tabbrowser-tab[fadein]:not([selected]) {
#tabbrowser-tabs[movingtab] > .tabbrowser-tab[fadein]:not([selected]) {
transition: transform 200ms var(--animation-easing-function);
}
@ -195,7 +195,7 @@ tabbrowser {
padding-bottom: 15px;
}
#TabsToolbar[movingtab] > .tabbrowser-tabs {
#TabsToolbar[movingtab] > #tabbrowser-tabs {
padding-bottom: 15px;
margin-bottom: -15px;
}

View File

@ -96,6 +96,12 @@
accesskey="&moveToNewWindow.accesskey;"
tbattr="tabbrowser-multiple"
oncommand="gBrowser.replaceTabWithWindow(TabContextMenu.contextTab);"/>
#ifdef E10S_TESTING_ONLY
<menuitem id="context_openNonRemoteWindow" label="Open in new non-e10s window"
tbattr="tabbrowser-remote"
hidden="true"
oncommand="gBrowser.openNonRemoteWindow(TabContextMenu.contextTab);"/>
#endif
<menuseparator id="context_sendTabToDevice_separator"/>
<menu id="context_sendTabToDevice" label="&sendTabToDevice.label;"
accesskey="&sendTabToDevice.accesskey;">
@ -628,7 +634,6 @@
#endif
<tabs id="tabbrowser-tabs"
class="tabbrowser-tabs"
tabbrowser="content"
flex="1"
setfocus="false"

View File

@ -15,7 +15,7 @@
}
.tab-close-button[pinned],
.tabbrowser-tabs[closebuttons="activetab"] > .tabbrowser-tab > .tab-stack > .tab-content > .tab-close-button:not([selected="true"]),
#tabbrowser-tabs[closebuttons="activetab"] > .tabbrowser-tab > .tab-stack > .tab-content > .tab-close-button:not([selected="true"]),
.tab-icon-image:not([src]):not([pinned]):not([crashed])[selected],
.tab-icon-image:not([src]):not([pinned]):not([crashed]):not([sharing]),
.tab-icon-image[busy],
@ -83,7 +83,7 @@ tabpanels {
pointer-events: none;
}
.tabbrowser-tabs:not(:hover) > .tabbrowser-arrowscrollbox > .closing-tabs-spacer {
#tabbrowser-tabs:not(:hover) > .tabbrowser-arrowscrollbox > .closing-tabs-spacer {
transition: width .15s ease-out;
}

View File

@ -3954,6 +3954,20 @@
</body>
</method>
<!-- Opens a given tab to a non-remote window. -->
<method name="openNonRemoteWindow">
<parameter name="aTab"/>
<body>
<![CDATA[
if (!AppConstants.E10S_TESTING_ONLY) {
throw "This method is intended only for e10s testing!";
}
let url = aTab.linkedBrowser.currentURI.spec;
return window.openDialog("chrome://browser/content/", "_blank", "chrome,all,dialog=no,non-remote", url);
]]>
</body>
</method>
<method name="moveTabTo">
<parameter name="aTab"/>
<parameter name="aIndex"/>
@ -5530,11 +5544,14 @@
}
} else {
label = tab._fullLabel || tab.getAttribute("label");
if (AppConstants.NIGHTLY_BUILD &&
if (AppConstants.E10S_TESTING_ONLY &&
tab.linkedBrowser &&
tab.linkedBrowser.isRemoteBrowser &&
tab.linkedBrowser.frameLoader) {
label += " (pid " + tab.linkedBrowser.frameLoader.tabParent.osPid + ")";
tab.linkedBrowser.isRemoteBrowser) {
label += " - e10s";
if (tab.linkedBrowser.frameLoader &&
Services.appinfo.maxWebProcessCount > 1) {
label += " (" + tab.linkedBrowser.frameLoader.tabParent.osPid + ")";
}
}
if (tab.userContextId) {
label = this.mStringBundle.getFormattedString("tabs.containers.tooltip", [label, ContextualIdentityService.getUserContextLabel(tab.userContextId)]);

View File

@ -17,6 +17,19 @@
<stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences.properties"/>
<preferences id="mainPreferences" hidden="true" data-category="paneGeneral">
#ifdef E10S_TESTING_ONLY
<preference id="browser.tabs.remote.autostart"
name="browser.tabs.remote.autostart"
type="bool"/>
<preference id="e10sTempPref"
name="browser.tabs.remote.autostart.2"
type="bool"/>
<preference id="e10sForceEnable"
name="browser.tabs.remote.force-enable"
type="bool"/>
#endif
<!-- Startup -->
<preference id="browser.startup.page"
name="browser.startup.page"
@ -159,10 +172,6 @@
name="layout.spellcheckDefault"
type="int"/>
<preference id="toolkit.telemetry.enabled"
name="toolkit.telemetry.enabled"
type="bool"/>
<preference id="browser.preferences.defaultPerformanceSettings.enabled"
name="browser.preferences.defaultPerformanceSettings.enabled"
type="bool"/>
@ -285,6 +294,11 @@
</vbox>
#endif
#ifdef E10S_TESTING_ONLY
<checkbox id="e10sAutoStart"
label="&e10sEnabled.label;"/>
#endif
#ifdef HAVE_SHELL_SERVICE
<vbox id="defaultBrowserBox">
<checkbox id="alwaysCheckDefault" preference="browser.shell.checkDefaultBrowser"

View File

@ -38,7 +38,7 @@ tabbrowser {
#tabbrowser-tabs,
#tabbrowser-tabs > .tabbrowser-arrowscrollbox,
.tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
#tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
min-height: var(--tab-min-height);
}

View File

@ -24,14 +24,12 @@ function TimingsPanel({ request }) {
return null;
}
const { timings, totalTime } = request.eventTimings;
const { timings, totalTime, offsets } = request.eventTimings;
const timelines = types.map((type, idx) => {
// Determine the relative offset for each timings box. For example, the
// offset of third timings box will be 0 + blocked offset + dns offset
const offset = types
.slice(0, idx)
.reduce((acc, cur) => (acc + timings[cur] || 0), 0);
const offsetScale = offset / totalTime || 0;
const offsetScale = offsets[type] / totalTime || 0;
const timelineScale = timings[type] / totalTime || 0;
return div({

View File

@ -7,7 +7,5 @@
const { LocalizationHelper } = require("devtools/shared/l10n");
const NET_STRINGS_URI = "devtools/client/locales/netmonitor.properties";
const WEBCONSOLE_STRINGS_URI = "devtools/client/locales/webconsole.properties";
exports.L10N = new LocalizationHelper(NET_STRINGS_URI);
exports.WEBCONSOLE_L10N = new LocalizationHelper(WEBCONSOLE_STRINGS_URI);

View File

@ -2124,7 +2124,8 @@ NetworkEventActor.prototype =
return {
from: this.actorID,
timings: this._timings,
totalTime: this._totalTime
totalTime: this._totalTime,
offsets: this._offsets
};
},
@ -2333,9 +2334,10 @@ NetworkEventActor.prototype =
* @param object timings
* Timing details about the network event.
*/
addEventTimings: function (total, timings) {
addEventTimings: function (total, timings, offsets) {
this._totalTime = total;
this._timings = timings;
this._offsets = offsets;
let packet = {
from: this.actorID,

View File

@ -913,7 +913,8 @@ NetworkMonitor.prototype = {
// There also is never any timing events, so we can fire this
// event with zeroed out values.
let timings = this._setupHarTimings(httpActivity, true);
httpActivity.owner.addEventTimings(timings.total, timings.timings);
httpActivity.owner.addEventTimings(timings.total, timings.timings,
timings.offsets);
}
},
@ -1363,7 +1364,8 @@ NetworkMonitor.prototype = {
*/
_onTransactionClose: function (httpActivity) {
let result = this._setupHarTimings(httpActivity);
httpActivity.owner.addEventTimings(result.total, result.timings);
httpActivity.owner.addEventTimings(result.total, result.timings,
result.offsets);
this.openRequests.delete(httpActivity.channel);
},
@ -1397,12 +1399,31 @@ NetworkMonitor.prototype = {
send: 0,
wait: 0,
receive: 0
},
offsets: {
blocked: 0,
dns: 0,
ssl: 0,
connect: 0,
send: 0,
wait: 0,
receive: 0
}
};
}
let timings = httpActivity.timings;
let harTimings = {};
// If the TCP Fast Open option or tls1.3 0RTT is used tls and data can
// be dispatched in SYN packet and not after tcp socket is connected.
// To demostrate this properly we will calculated TLS and send start time
// relative to CONNECTING_TO.
// Similary if 0RTT is used, data can be sent as soon as a TLS handshake
// starts.
let secureConnectionStartTime = 0;
let secureConnectionStartTimeRelative = false;
let startSendingTime = 0;
let startSendingTimeRelative = false;
if (timings.STATUS_RESOLVING && timings.STATUS_CONNECTING_TO) {
harTimings.blocked = timings.STATUS_RESOLVING.first -
@ -1430,6 +1451,14 @@ NetworkMonitor.prototype = {
if (timings.STATUS_TLS_STARTING && timings.STATUS_TLS_ENDING) {
harTimings.ssl = timings.STATUS_TLS_ENDING.last -
timings.STATUS_TLS_STARTING.first;
if (timings.STATUS_CONNECTING_TO) {
secureConnectionStartTime =
timings.STATUS_TLS_STARTING.first - timings.STATUS_CONNECTING_TO.first;
}
if (secureConnectionStartTime < 0) {
secureConnectionStartTime = 0;
}
secureConnectionStartTimeRelative = true;
} else {
harTimings.ssl = -1;
}
@ -1439,26 +1468,93 @@ NetworkMonitor.prototype = {
// nsITimedChannel interface used by Resource and Navigation Timing
let timedChannel = httpActivity.channel.QueryInterface(Ci.nsITimedChannel);
if ((harTimings.connect <= 0) && timedChannel) {
if (timedChannel.secureConnectionStartTime > timedChannel.connectStartTime) {
harTimings.connect =
timedChannel.secureConnectionStartTime - timedChannel.connectStartTime;
harTimings.ssl =
timedChannel.connectEndTime - timedChannel.secureConnectionStartTime;
} else {
harTimings.connect =
timedChannel.connectEndTime - timedChannel.connectStartTime;
harTimings.ssl = -1;
let tcTcpConnectEndTime = 0;
let tcConnectStartTime = 0;
let tcConnectEndTime = 0;
let tcSecureConnectionStartTime = 0;
let tcDomainLookupEndTime = 0;
let tcDomainLookupStartTime = 0;
if (timedChannel) {
tcTcpConnectEndTime = timedChannel.tcpConnectEndTime;
tcConnectStartTime = timedChannel.connectStartTime;
tcConnectEndTime = timedChannel.connectEndTime;
tcSecureConnectionStartTime = timedChannel.secureConnectionStartTime;
tcDomainLookupEndTime = timedChannel.domainLookupEndTime;
tcDomainLookupStartTime = timedChannel.domainLookupStartTime;
}
// Make sure the above values are at least timedChannel.asyncOpenTime.
if (timedChannel && timedChannel.asyncOpenTime) {
if ((tcTcpConnectEndTime != 0) &&
(tcTcpConnectEndTime < timedChannel.asyncOpenTime)) {
tcTcpConnectEndTime = 0;
}
if ((tcConnectStartTime != 0) &&
(tcConnectStartTime < timedChannel.asyncOpenTime)) {
tcConnectStartTime = 0;
}
if ((tcConnectEndTime != 0) &&
(tcConnectEndTime < timedChannel.asyncOpenTime)) {
tcConnectEndTime = 0;
}
if ((tcSecureConnectionStartTime != 0) &&
(tcSecureConnectionStartTime < timedChannel.asyncOpenTime)) {
tcSecureConnectionStartTime = 0;
}
if ((tcDomainLookupEndTime != 0) &&
(tcDomainLookupEndTime < timedChannel.asyncOpenTime)) {
tcDomainLookupEndTime = 0;
}
if ((tcDomainLookupStartTime != 0) &&
(tcDomainLookupStartTime < timedChannel.asyncOpenTime)) {
tcDomainLookupStartTime = 0;
}
}
if ((harTimings.dns <= 0) && timedChannel) {
harTimings.dns =
timedChannel.domainLookupEndTime - timedChannel.domainLookupStartTime;
if ((harTimings.connect <= 0) && timedChannel &&
(tcTcpConnectEndTime != 0) && (tcConnectStartTime != 0)) {
harTimings.connect = tcTcpConnectEndTime - tcConnectStartTime;
if (tcSecureConnectionStartTime != 0) {
harTimings.ssl = tcConnectEndTime - tcSecureConnectionStartTime;
secureConnectionStartTime =
tcSecureConnectionStartTime - tcConnectStartTime;
secureConnectionStartTimeRelative = true;
} else {
harTimings.ssl = -1;
}
} else if (timedChannel && timings.STATUS_TLS_STARTING &&
(tcSecureConnectionStartTime != 0)) {
// It can happen that TCP Fast Open actually have not sent any data and
// timings.STATUS_TLS_STARTING.first value will be corrected in
// timedChannel.secureConnectionStartTime
if (tcSecureConnectionStartTime > timings.STATUS_TLS_STARTING.first) {
// TCP Fast Open actually did not sent any data.
harTimings.ssl =
tcConnectEndTime - tcSecureConnectionStartTime;
secureConnectionStartTimeRelative = false;
}
}
if ((harTimings.dns <= 0) && timedChannel &&
(tcDomainLookupEndTime != 0) && (tcDomainLookupStartTime != 0)) {
harTimings.dns = tcDomainLookupEndTime - tcDomainLookupStartTime;
}
if (timings.STATUS_SENDING_TO) {
harTimings.send = timings.STATUS_SENDING_TO.last - timings.STATUS_SENDING_TO.first;
harTimings.send =
timings.STATUS_SENDING_TO.last - timings.STATUS_SENDING_TO.first;
if (timings.STATUS_CONNECTING_TO) {
startSendingTime =
timings.STATUS_SENDING_TO.first - timings.STATUS_CONNECTING_TO.first;
startSendingTimeRelative = true;
} else if (tcConnectStartTime != 0) {
startSendingTime = timings.STATUS_SENDING_TO.first - tcConnectStartTime;
startSendingTimeRelative = true;
}
if (startSendingTime < 0) {
startSendingTime = 0;
}
} else if (timings.REQUEST_HEADER && timings.REQUEST_BODY_SENT) {
harTimings.send = timings.REQUEST_BODY_SENT.last - timings.REQUEST_HEADER.first;
} else {
@ -1480,18 +1576,72 @@ NetworkMonitor.prototype = {
harTimings.receive = -1;
}
if (secureConnectionStartTimeRelative) {
let time = Math.max(Math.round(secureConnectionStartTime / 1000), -1);
secureConnectionStartTime = time;
}
if (startSendingTimeRelative) {
let time = Math.max(Math.round(startSendingTime / 1000), -1);
startSendingTime = time;
}
let ot = this._calculateOffsetAndTotalTime(harTimings,
secureConnectionStartTime,
startSendingTimeRelative,
secureConnectionStartTimeRelative,
startSendingTime);
return {
total: ot.total,
timings: harTimings,
offsets: ot.offsets
};
},
_calculateOffsetAndTotalTime: function (harTimings,
secureConnectionStartTime,
startSendingTimeRelative,
secureConnectionStartTimeRelative,
startSendingTime) {
let totalTime = 0;
for (let timing in harTimings) {
let time = Math.max(Math.round(harTimings[timing] / 1000), -1);
harTimings[timing] = time;
if (time > -1) {
if ((time > -1) && (timing != "connect") && (timing != "ssl")) {
totalTime += time;
}
}
// connect, ssl and send times can be overlapped.
if (startSendingTimeRelative) {
totalTime += startSendingTime;
} else if (secureConnectionStartTimeRelative) {
totalTime += secureConnectionStartTime;
totalTime += harTimings.ssl;
}
let offsets = {};
offsets.blocked = 0;
offsets.dns = harTimings.blocked;
offsets.connect = offsets.dns + harTimings.dns;
if (secureConnectionStartTimeRelative) {
offsets.ssl = offsets.connect + secureConnectionStartTime;
} else {
offsets.ssl = offsets.connect + harTimings.connect;
}
if (startSendingTimeRelative) {
offsets.send = offsets.connect + startSendingTime;
if (!secureConnectionStartTimeRelative) {
offsets.ssl = offsets.send - harTimings.ssl;
}
} else {
offsets.send = offsets.ssl + harTimings.ssl;
}
offsets.wait = offsets.send + harTimings.send;
offsets.receive = offsets.wait + harTimings.wait;
return {
total: totalTime,
timings: harTimings,
offsets: offsets
};
},

View File

@ -9959,10 +9959,13 @@ nsDocShell::InternalLoad(nsIURI* aURI,
isTargetTopLevelDocShell = true;
}
nsIDocument* doc = mContentViewer ? mContentViewer->GetDocument()
: nullptr;
if (!nsContentSecurityManager::AllowTopLevelNavigationToDataURI(
aURI,
contentType,
aTriggeringPrincipal,
doc,
(aLoadType == LOAD_NORMAL_EXTERNAL),
!aFileName.IsVoid())) {
// logging to console happens within AllowTopLevelNavigationToDataURI
@ -10097,8 +10100,6 @@ nsDocShell::InternalLoad(nsIURI* aURI,
}
}
const nsIDocument* doc = mContentViewer ? mContentViewer->GetDocument()
: nullptr;
const bool isDocumentAuxSandboxed = doc &&
(doc->GetSandboxFlags() & SANDBOXED_AUXILIARY_NAVIGATION);

View File

@ -1043,18 +1043,40 @@ nsContentUtils::Atob(const nsAString& aAsciiBase64String,
}
const char16_t* start = aAsciiBase64String.BeginReading();
const char16_t* cur = start;
const char16_t* end = aAsciiBase64String.EndReading();
nsString trimmedString;
if (!trimmedString.SetCapacity(aAsciiBase64String.Length(), fallible)) {
return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
}
while (start < end) {
if (!nsContentUtils::IsHTMLWhitespace(*start)) {
trimmedString.Append(*start);
bool hasWhitespace = false;
while (cur < end) {
if (nsContentUtils::IsHTMLWhitespace(*cur)) {
hasWhitespace = true;
break;
}
start++;
cur++;
}
nsresult rv = Base64Decode(trimmedString, aBinaryData);
nsresult rv;
if (hasWhitespace) {
nsString trimmedString;
if (!trimmedString.SetCapacity(aAsciiBase64String.Length(), fallible)) {
return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
}
trimmedString.Append(start, cur - start);
while (cur < end) {
if (!nsContentUtils::IsHTMLWhitespace(*cur)) {
trimmedString.Append(*cur);
}
cur++;
}
rv = Base64Decode(trimmedString, aBinaryData);
} else {
rv = Base64Decode(aAsciiBase64String, aBinaryData);
}
if (NS_FAILED(rv) && rv == NS_ERROR_INVALID_ARG) {
return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
}

View File

@ -628,6 +628,7 @@ skip-if = toolkit == 'android'
skip-if = toolkit == 'android'
[test_bug1399603.html]
[test_bug1399605.html]
[test_bug1404385.html]
[test_bug1406102.html]
[test_caretPositionFromPoint.html]
[test_change_policy.html]

View File

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1404385
-->
<head>
<title>Test for Bug 1404385</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1404385">Mozilla Bug 1404385</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 1404385 **/
is(atob("T0s="), "OK", "atob");
is(atob(" T0s="), "OK", "atob initial space removal");
is(atob("T0s= "), "OK", "atob final space removal");
is(atob("T 0s="), "OK", "atob middle space removal");
is(atob("dGV zdA=="), "test", "atob middle space removal 2");
is(atob(""), "", "atob empty string");
is(atob(" "), "", "atob all whitespace");
</script>
</pre>
</body>
</html>

View File

@ -189,11 +189,16 @@ Blob::GetType(nsAString &aType)
already_AddRefed<Blob>
Blob::Slice(const Optional<int64_t>& aStart,
const Optional<int64_t>& aEnd,
const nsAString& aContentType,
const Optional<nsAString>& aContentType,
ErrorResult& aRv)
{
nsAutoString contentType;
if (aContentType.WasPassed()) {
contentType = aContentType.Value();
}
RefPtr<BlobImpl> impl =
mImpl->Slice(aStart, aEnd, aContentType, aRv);
mImpl->Slice(aStart, aEnd, contentType, aRv);
if (aRv.Failed()) {
return nullptr;
}

View File

@ -122,7 +122,7 @@ public:
already_AddRefed<Blob> Slice(const Optional<int64_t>& aStart,
const Optional<int64_t>& aEnd,
const nsAString& aContentType,
const Optional<nsAString>& aContentType,
ErrorResult& aRv);
size_t GetAllocationSize() const;

View File

@ -19,6 +19,7 @@
#include "mozilla/dom/FileReaderBinding.h"
#include "mozilla/dom/ProgressEvent.h"
#include "mozilla/Encoding.h"
#include "nsAlgorithm.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDOMJSUtils.h"
#include "nsError.h"
@ -187,27 +188,6 @@ FileReader::GetResult(JSContext* aCx,
}
}
static nsresult
ReadFuncBinaryString(nsIInputStream* in,
void* closure,
const char* fromRawSegment,
uint32_t toOffset,
uint32_t count,
uint32_t *writeCount)
{
char16_t* dest = static_cast<char16_t*>(closure) + toOffset;
char16_t* end = dest + count;
const unsigned char* source = (const unsigned char*)fromRawSegment;
while (dest != end) {
*dest = *source;
++dest;
++source;
}
*writeCount = count;
return NS_OK;
}
void
FileReader::OnLoadEndArrayBuffer()
{
@ -293,32 +273,56 @@ FileReader::DoReadData(uint64_t aCount)
if (mDataFormat == FILE_AS_BINARY) {
//Continuously update our binary string as data comes in
uint32_t oldLen = mResult.Length();
MOZ_ASSERT(mResult.Length() == mDataLen, "unexpected mResult length");
if (uint64_t(oldLen) + aCount > UINT32_MAX)
CheckedInt<uint64_t> size = mResult.Length();
size += aCount;
if (!size.isValid() ||
size.value() > UINT32_MAX ||
size.value() > mTotal) {
return NS_ERROR_OUT_OF_MEMORY;
char16_t *buf = nullptr;
mResult.GetMutableData(&buf, oldLen + aCount, fallible);
NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
}
nsresult rv;
uint32_t oldLen = mResult.Length();
MOZ_ASSERT(oldLen == mDataLen, "unexpected mResult length");
char16_t* dest = nullptr;
mResult.GetMutableData(&dest, size.value(), fallible);
NS_ENSURE_TRUE(dest, NS_ERROR_OUT_OF_MEMORY);
dest += oldLen;
while (aCount > 0) {
char tmpBuffer[4096];
uint32_t minCount =
XPCOM_MIN(aCount, static_cast<uint64_t>(sizeof(tmpBuffer)));
uint32_t read;
nsresult rv = mAsyncStream->Read(tmpBuffer, minCount, &read);
if (rv == NS_BASE_STREAM_CLOSED) {
rv = NS_OK;
}
// nsFileStreams do not implement ReadSegment. In case here we are dealing
// with a nsIAsyncInputStream, in content process, we need to wrap a
// nsIBufferedInputStream around it.
if (!mBufferedStream) {
rv = NS_NewBufferedInputStream(getter_AddRefs(mBufferedStream),
mAsyncStream, 8192);
NS_ENSURE_SUCCESS(rv, rv);
if (read == 0) {
// The stream finished too early.
return NS_ERROR_OUT_OF_MEMORY;
}
char16_t* end = dest + read;
const unsigned char* source = (const unsigned char*)tmpBuffer;
while (dest != end) {
*dest = *source;
++dest;
++source;
}
aCount -= read;
bytesRead += read;
}
rv = mBufferedStream->ReadSegments(ReadFuncBinaryString, buf + oldLen,
aCount, &bytesRead);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mResult.Truncate(oldLen + bytesRead);
MOZ_ASSERT(size.value() == oldLen + bytesRead);
mResult.Truncate(size.value());
}
else {
CheckedInt<uint64_t> size = mDataLen;
@ -366,7 +370,6 @@ FileReader::ReadFileContent(Blob& aBlob,
mResultArrayBuffer = nullptr;
mAsyncStream = nullptr;
mBufferedStream = nullptr;
mTransferred = 0;
mTotal = 0;
@ -558,7 +561,6 @@ FileReader::FreeDataAndDispatchSuccess()
FreeFileData();
mResult.SetIsVoid(false);
mAsyncStream = nullptr;
mBufferedStream = nullptr;
mBlob = nullptr;
// Dispatch event to signify end of a successful operation
@ -574,7 +576,6 @@ FileReader::FreeDataAndDispatchError()
FreeFileData();
mResult.SetIsVoid(true);
mAsyncStream = nullptr;
mBufferedStream = nullptr;
mBlob = nullptr;
// Dispatch error event to signify load failure
@ -769,7 +770,6 @@ FileReader::Abort()
mResultArrayBuffer = nullptr;
mAsyncStream = nullptr;
mBufferedStream = nullptr;
mBlob = nullptr;
//Clean up memory buffer
@ -823,11 +823,6 @@ FileReader::Shutdown()
mAsyncStream = nullptr;
}
if (mBufferedStream) {
mBufferedStream->Close();
mBufferedStream = nullptr;
}
FreeFileData();
mResultArrayBuffer = nullptr;

View File

@ -72,9 +72,14 @@ public:
ReadFileContent(aBlob, EmptyString(), FILE_AS_ARRAYBUFFER, aRv);
}
void ReadAsText(Blob& aBlob, const nsAString& aLabel, ErrorResult& aRv)
void ReadAsText(Blob& aBlob, const Optional<nsAString>& aLabel,
ErrorResult& aRv)
{
ReadFileContent(aBlob, aLabel, FILE_AS_TEXT, aRv);
if (aLabel.WasPassed()) {
ReadFileContent(aBlob, aLabel.Value(), FILE_AS_TEXT, aRv);
} else {
ReadFileContent(aBlob, EmptyString(), FILE_AS_TEXT, aRv);
}
}
void ReadAsDataURL(Blob& aBlob, ErrorResult& aRv)
@ -183,7 +188,6 @@ private:
bool mTimerIsActive;
nsCOMPtr<nsIAsyncInputStream> mAsyncStream;
nsCOMPtr<nsIInputStream> mBufferedStream;
RefPtr<DOMException> mError;

View File

@ -378,7 +378,8 @@ HTMLLinkElement::GetLinkTarget(nsAString& aTarget)
static const DOMTokenListSupportedToken sSupportedRelValues[] = {
// Keep this in sync with ToLinkMask in nsStyleLinkElement.cpp.
// "import" must come first because it's conditional.
// "preload" must come first because it can be disabled.
"preload",
"prefetch",
"dns-prefetch",
"stylesheet",
@ -387,23 +388,9 @@ static const DOMTokenListSupportedToken sSupportedRelValues[] = {
"preconnect",
"icon",
"search",
"preload",
nullptr
};
static const DOMTokenListSupportedToken sSupportedRelValuesNoPreload[] = {
// Keep this in sync with ToLinkMask in nsStyleLinkElement.cpp.
// "import" must come first because it's conditional.
"prefetch",
"dns-prefetch",
"stylesheet",
"next",
"alternate",
"preconnect",
"icon",
"search",
nullptr
};
nsDOMTokenList*
HTMLLinkElement::RelList()
{
@ -411,7 +398,7 @@ HTMLLinkElement::RelList()
if (Preferences::GetBool("network.preload")) {
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, sSupportedRelValues);
} else {
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, sSupportedRelValuesNoPreload);
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, &sSupportedRelValues[1]);
}
}
return mRelList;

View File

@ -302,9 +302,9 @@ MediaSourceTrackDemuxer::MediaSourceTrackDemuxer(MediaSourceDemuxer* aParent,
TrackInfo::TrackType aType,
TrackBuffersManager* aManager)
: mParent(aParent)
, mManager(aManager)
, mType(aType)
, mMonitor("MediaSourceTrackDemuxer")
, mManager(aManager)
, mReset(true)
, mPreRoll(TimeUnit::FromMicroseconds(
OpusDataDecoder::IsOpus(mParent->GetTrackInfo(mType)->mMimeType)
@ -354,6 +354,7 @@ MediaSourceTrackDemuxer::Reset()
if (!self->mManager) {
return;
}
MOZ_ASSERT(self->OnTaskQueue());
self->mManager->Seek(self->mType, TimeUnit::Zero(), TimeUnit::Zero());
{
MonitorAutoLock mon(self->mMonitor);
@ -385,6 +386,7 @@ MediaSourceTrackDemuxer::SkipToNextRandomAccessPoint(
media::TimeIntervals
MediaSourceTrackDemuxer::GetBuffered()
{
MonitorAutoLock mon(mMonitor);
if (!mManager) {
return media::TimeIntervals();
}
@ -397,8 +399,8 @@ MediaSourceTrackDemuxer::BreakCycles()
RefPtr<MediaSourceTrackDemuxer> self = this;
nsCOMPtr<nsIRunnable> task =
NS_NewRunnableFunction("MediaSourceTrackDemuxer::BreakCycles", [self]() {
self->mParent = nullptr;
self->DetachManager();
self->mParent = nullptr;
});
mParent->GetTaskQueue()->Dispatch(task.forget());
}
@ -411,6 +413,8 @@ MediaSourceTrackDemuxer::DoSeek(const TimeUnit& aTime)
MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
RESULT_DETAIL("manager is detached.")), __func__);
}
MOZ_ASSERT(OnTaskQueue());
TimeIntervals buffered = mManager->Buffered(mType);
// Fuzz factor represents a +/- threshold. So when seeking it allows the gap
// to be twice as big as the fuzz value. We only want to allow EOS_FUZZ gap.
@ -463,6 +467,8 @@ MediaSourceTrackDemuxer::DoGetSamples(int32_t aNumSamples)
MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
RESULT_DETAIL("manager is detached.")), __func__);
}
MOZ_ASSERT(OnTaskQueue());
if (mReset) {
// If a seek (or reset) was recently performed, we ensure that the data
// we are about to retrieve is still available.
@ -516,6 +522,8 @@ MediaSourceTrackDemuxer::DoSkipToNextRandomAccessPoint(
SkipFailureHolder(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
RESULT_DETAIL("manager is detached.")), 0), __func__);
}
MOZ_ASSERT(OnTaskQueue());
uint32_t parsed = 0;
// Ensure that the data we are about to skip to is still available.
TimeIntervals buffered = mManager->Buffered(mType);
@ -539,12 +547,15 @@ MediaSourceTrackDemuxer::DoSkipToNextRandomAccessPoint(
bool
MediaSourceTrackDemuxer::HasManager(TrackBuffersManager* aManager) const
{
MOZ_ASSERT(OnTaskQueue());
return mManager == aManager;
}
void
MediaSourceTrackDemuxer::DetachManager()
{
MOZ_ASSERT(OnTaskQueue());
MonitorAutoLock mon(mMonitor);
mManager = nullptr;
}

View File

@ -120,6 +120,15 @@ public:
void DetachManager();
private:
bool OnTaskQueue() const
{
MOZ_ASSERT(mParent);
auto taskQueue = mParent->GetTaskQueue();
MOZ_ASSERT(taskQueue);
return taskQueue->IsCurrentThreadIn();
}
RefPtr<SeekPromise> DoSeek(const media::TimeUnit& aTime);
RefPtr<SamplesPromise> DoGetSamples(int32_t aNumSamples);
RefPtr<SkipAccessPointPromise> DoSkipToNextRandomAccessPoint(
@ -129,11 +138,15 @@ private:
media::TimeUnit GetNextRandomAccessPoint();
RefPtr<MediaSourceDemuxer> mParent;
RefPtr<TrackBuffersManager> mManager;
TrackInfo::TrackType mType;
// Monitor protecting members below accessed from multiple threads.
Monitor mMonitor;
media::TimeUnit mNextRandomAccessPoint;
// Would be accessed in MFR's demuxer proxy task queue and TaskQueue, and
// only be set on the TaskQueue. It can be accessed while on TaskQueue without
// the need for the lock.
RefPtr<TrackBuffersManager> mManager;
Maybe<RefPtr<MediaRawData>> mNextSample;
// Set to true following a reset. Ensure that the next sample demuxed
// is available at position 0.

View File

@ -275,7 +275,7 @@ skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulato
[test_peerConnection_verifyVideoAfterRenegotiation.html]
skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_videoCodecs.html]
skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator), android(Bug 1409203, failures on Autophone)
[test_peerConnection_audioRenegotiationInactiveAnswer.html]
skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_videoRenegotiationInactiveAnswer.html]

View File

@ -26,6 +26,7 @@ nsContentSecurityManager::AllowTopLevelNavigationToDataURI(
nsIURI* aURI,
nsContentPolicyType aContentPolicyType,
nsIPrincipal* aTriggeringPrincipal,
nsIDocument* aDoc,
bool aLoadFromExternal,
bool aIsDownLoad)
{
@ -73,8 +74,7 @@ nsContentSecurityManager::AllowTopLevelNavigationToDataURI(
const char16_t* params[] = { specUTF16.get() };
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("DATA_URI_BLOCKED"),
// no doc available, log to browser console
nullptr,
aDoc,
nsContentUtils::eSECURITY_PROPERTIES,
"BlockTopLevelDataURINavigation",
params, ArrayLength(params));
@ -584,6 +584,7 @@ nsContentSecurityManager::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
uri,
newLoadInfo->GetExternalContentPolicyType(),
nullTriggeringPrincipal,
nullptr, // no doc available, log to browser console
false,
false)) {
// logging to console happens within AllowTopLevelNavigationToDataURI

View File

@ -12,6 +12,7 @@
#include "nsIChannelEventSink.h"
class nsIStreamListener;
class nsIDocument;
#define NS_CONTENTSECURITYMANAGER_CONTRACTID "@mozilla.org/contentsecuritymanager;1"
// cdcc1ab8-3cea-4e6c-a294-a651fa35227f
@ -35,6 +36,7 @@ public:
static bool AllowTopLevelNavigationToDataURI(nsIURI* aURI,
nsContentPolicyType aContentPolicyType,
nsIPrincipal* aTriggeringPrincipal,
nsIDocument* aDoc,
bool aLoadFromExternal,
bool aIsDownload);

View File

@ -249,10 +249,9 @@ U2FManager::Register(nsPIDOMWindowInner* aParent, const nsCString& aRpId,
p->Then(GetMainThreadSerialEventTarget(), __func__,
[]() {
U2FManager* mgr = U2FManager::Get();
if (!mgr) {
return;
if (mgr && mgr->mChild) {
mgr->mChild->SendRequestRegister(mgr->mInfo.ref());
}
mgr->StartRegister();
},
[]() {
// This case can't actually happen, we'll have crashed if the child
@ -287,10 +286,9 @@ U2FManager::Sign(nsPIDOMWindowInner* aParent,
p->Then(GetMainThreadSerialEventTarget(), __func__,
[]() {
U2FManager* mgr = U2FManager::Get();
if (!mgr) {
return;
if (mgr && mgr->mChild) {
mgr->mChild->SendRequestSign(mgr->mInfo.ref());
}
mgr->StartSign();
},
[]() {
// This case can't actually happen, we'll have crashed if the child
@ -305,27 +303,6 @@ U2FManager::Sign(nsPIDOMWindowInner* aParent,
return promise.forget();
}
void
U2FManager::StartRegister() {
if (mChild) {
mChild->SendRequestRegister(mInfo.ref());
}
}
void
U2FManager::StartSign() {
if (mChild) {
mChild->SendRequestSign(mInfo.ref());
}
}
void
U2FManager::StartCancel() {
if (mChild) {
mChild->SendRequestCancel();
}
}
void
U2FManager::FinishRegister(nsTArray<uint8_t>& aRegBuffer)
{
@ -427,6 +404,14 @@ U2FManager::FinishSign(nsTArray<uint8_t>& aCredentialId,
MaybeClearTransaction();
}
void
U2FManager::RequestAborted(const nsresult& aError)
{
MOZ_ASSERT(NS_IsMainThread());
Cancel(aError);
}
void
U2FManager::Cancel(const nsresult& aError)
{
@ -444,7 +429,9 @@ U2FManager::Cancel(const nsresult& aError)
NS_IMETHODIMP
U2FManager::HandleEvent(nsIDOMEvent* aEvent)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aEvent);
MOZ_ASSERT(mChild);
nsAutoString type;
aEvent->GetType(type);
@ -460,7 +447,8 @@ U2FManager::HandleEvent(nsIDOMEvent* aEvent)
MOZ_LOG(gU2FManagerLog, LogLevel::Debug,
("Visibility change: U2F window is hidden, cancelling job."));
StartCancel();
mChild->SendRequestCancel();
Cancel(NS_ERROR_DOM_TIMEOUT_ERR);
}

View File

@ -59,14 +59,11 @@ class U2FManager final : public nsIIPCBackgroundChildCreateCallback
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMEVENTLISTENER
NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
static U2FManager* GetOrCreate();
static U2FManager* Get();
void FinishRegister(nsTArray<uint8_t>& aRegBuffer);
void FinishSign(nsTArray<uint8_t>& aCredentialId,
nsTArray<uint8_t>& aSigBuffer);
void Cancel(const nsresult& aError);
already_AddRefed<U2FPromise> Register(nsPIDOMWindowInner* aParent,
const nsCString& aRpId,
const nsCString& aClientDataJSON,
@ -78,14 +75,15 @@ public:
const uint32_t& aTimeoutMillis,
const nsTArray<WebAuthnScopedCredentialDescriptor>& aKeyList);
void StartRegister();
void StartSign();
void StartCancel();
void FinishRegister(nsTArray<uint8_t>& aRegBuffer);
void FinishSign(nsTArray<uint8_t>& aCredentialId,
nsTArray<uint8_t>& aSigBuffer);
void RequestAborted(const nsresult& aError);
void Cancel(const nsresult& aError);
// nsIIPCbackgroundChildCreateCallback methods
void ActorCreated(PBackgroundChild* aActor) override;
void ActorFailed() override;
void ActorDestroyed();
private:
U2FManager();
virtual ~U2FManager();

View File

@ -37,11 +37,11 @@ U2FTransactionChild::RecvConfirmSign(nsTArray<uint8_t>&& aCredentialId,
}
mozilla::ipc::IPCResult
U2FTransactionChild::RecvCancel(const nsresult& aError)
U2FTransactionChild::RecvAbort(const nsresult& aError)
{
RefPtr<U2FManager> mgr = U2FManager::Get();
MOZ_ASSERT(mgr);
mgr->Cancel(aError);
mgr->RequestAborted(aError);
return IPC_OK();
}

View File

@ -26,7 +26,7 @@ public:
mozilla::ipc::IPCResult RecvConfirmRegister(nsTArray<uint8_t>&& aRegBuffer) override;
mozilla::ipc::IPCResult RecvConfirmSign(nsTArray<uint8_t>&& aCredentialId,
nsTArray<uint8_t>&& aBuffer) override;
mozilla::ipc::IPCResult RecvCancel(const nsresult& aError) override;
mozilla::ipc::IPCResult RecvAbort(const nsresult& aError) override;
void ActorDestroy(ActorDestroyReason why) override;
private:
~U2FTransactionChild() = default;

View File

@ -45,7 +45,7 @@ async protocol PWebAuthnTransaction {
child:
async ConfirmRegister(uint8_t[] RegBuffer);
async ConfirmSign(uint8_t[] CredentialID, uint8_t[] ReplyBuffer);
async Cancel(nsresult Error);
async Abort(nsresult Error);
};
}

View File

@ -160,7 +160,7 @@ U2FTokenManager::Get()
void
U2FTokenManager::AbortTransaction(const nsresult& aError)
{
Unused << mTransactionParent->SendCancel(aError);
Unused << mTransactionParent->SendAbort(aError);
ClearTransaction();
}

View File

@ -442,10 +442,9 @@ WebAuthnManager::MakeCredential(nsPIDOMWindowInner* aParent,
p->Then(GetMainThreadSerialEventTarget(), __func__,
[]() {
WebAuthnManager* mgr = WebAuthnManager::Get();
if (!mgr) {
return;
if (mgr && mgr->mChild) {
mgr->mChild->SendRequestRegister(mgr->mInfo.ref());
}
mgr->StartRegister();
},
[]() {
// This case can't actually happen, we'll have crashed if the child
@ -460,33 +459,6 @@ WebAuthnManager::MakeCredential(nsPIDOMWindowInner* aParent,
return promise.forget();
}
void
WebAuthnManager::StartRegister() {
MOZ_ASSERT(NS_IsMainThread());
if (mChild) {
mChild->SendRequestRegister(mInfo.ref());
}
}
void
WebAuthnManager::StartSign() {
MOZ_ASSERT(NS_IsMainThread());
if (mChild) {
mChild->SendRequestSign(mInfo.ref());
}
}
void
WebAuthnManager::StartCancel() {
MOZ_ASSERT(NS_IsMainThread());
if (mChild) {
mChild->SendRequestCancel();
}
}
already_AddRefed<Promise>
WebAuthnManager::GetAssertion(nsPIDOMWindowInner* aParent,
const PublicKeyCredentialRequestOptions& aOptions)
@ -620,10 +592,9 @@ WebAuthnManager::GetAssertion(nsPIDOMWindowInner* aParent,
p->Then(GetMainThreadSerialEventTarget(), __func__,
[]() {
WebAuthnManager* mgr = WebAuthnManager::Get();
if (!mgr) {
return;
if (mgr && mgr->mChild) {
mgr->mChild->SendRequestSign(mgr->mInfo.ref());
}
mgr->StartSign();
},
[]() {
// This case can't actually happen, we'll have crashed if the child
@ -866,6 +837,14 @@ WebAuthnManager::FinishGetAssertion(nsTArray<uint8_t>& aCredentialId,
MaybeClearTransaction();
}
void
WebAuthnManager::RequestAborted(const nsresult& aError)
{
MOZ_ASSERT(NS_IsMainThread());
Cancel(aError);
}
void
WebAuthnManager::Cancel(const nsresult& aError)
{
@ -883,6 +862,7 @@ WebAuthnManager::HandleEvent(nsIDOMEvent* aEvent)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aEvent);
MOZ_ASSERT(mChild);
nsAutoString type;
aEvent->GetType(type);
@ -898,7 +878,8 @@ WebAuthnManager::HandleEvent(nsIDOMEvent* aEvent)
MOZ_LOG(gWebAuthnManagerLog, LogLevel::Debug,
("Visibility change: WebAuthn window is hidden, cancelling job."));
StartCancel();
mChild->SendRequestCancel();
Cancel(NS_ERROR_ABORT);
}

View File

@ -68,19 +68,11 @@ class WebAuthnManager final : public nsIIPCBackgroundChildCreateCallback,
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMEVENTLISTENER
NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
static WebAuthnManager* GetOrCreate();
static WebAuthnManager* Get();
void
FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer);
void
FinishGetAssertion(nsTArray<uint8_t>& aCredentialId,
nsTArray<uint8_t>& aSigBuffer);
void
Cancel(const nsresult& aError);
already_AddRefed<Promise>
MakeCredential(nsPIDOMWindowInner* aParent,
const MakePublicKeyCredentialOptions& aOptions);
@ -92,18 +84,23 @@ public:
already_AddRefed<Promise>
Store(nsPIDOMWindowInner* aParent, const Credential& aCredential);
void StartRegister();
void StartSign();
void StartCancel();
void
FinishMakeCredential(nsTArray<uint8_t>& aRegBuffer);
void
FinishGetAssertion(nsTArray<uint8_t>& aCredentialId,
nsTArray<uint8_t>& aSigBuffer);
void
RequestAborted(const nsresult& aError);
// nsIIPCbackgroundChildCreateCallback methods
void ActorCreated(PBackgroundChild* aActor) override;
void ActorFailed() override;
void ActorDestroyed();
private:
WebAuthnManager();
virtual ~WebAuthnManager();
void Cancel(const nsresult& aError);
void MaybeClearTransaction();
typedef MozPromise<nsresult, nsresult, false> BackgroundActorPromise;

View File

@ -38,11 +38,11 @@ WebAuthnTransactionChild::RecvConfirmSign(nsTArray<uint8_t>&& aCredentialId,
}
mozilla::ipc::IPCResult
WebAuthnTransactionChild::RecvCancel(const nsresult& aError)
WebAuthnTransactionChild::RecvAbort(const nsresult& aError)
{
RefPtr<WebAuthnManager> mgr = WebAuthnManager::Get();
MOZ_ASSERT(mgr);
mgr->Cancel(aError);
mgr->RequestAborted(aError);
return IPC_OK();
}

View File

@ -27,7 +27,7 @@ public:
mozilla::ipc::IPCResult RecvConfirmRegister(nsTArray<uint8_t>&& aRegBuffer) override;
mozilla::ipc::IPCResult RecvConfirmSign(nsTArray<uint8_t>&& aCredentialId,
nsTArray<uint8_t>&& aBuffer) override;
mozilla::ipc::IPCResult RecvCancel(const nsresult& aError) override;
mozilla::ipc::IPCResult RecvAbort(const nsresult& aError) override;
void ActorDestroy(ActorDestroyReason why) override;
private:
~WebAuthnTransactionChild() = default;

View File

@ -27,7 +27,7 @@ interface Blob {
[Throws]
Blob slice([Clamp] optional long long start,
[Clamp] optional long long end,
optional DOMString contentType = "");
optional DOMString contentType);
};
enum EndingTypes { "transparent", "native" };

View File

@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://dev.w3.org/2006/webapi/FileAPI/#dfn-filereader
* https://w3c.github.io/FileAPI/#APIASynch
*
* Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
@ -17,7 +17,9 @@ interface FileReader : EventTarget {
[Throws]
void readAsArrayBuffer(Blob blob);
[Throws]
void readAsText(Blob blob, optional DOMString label = "");
void readAsBinaryString(Blob filedata);
[Throws]
void readAsText(Blob blob, optional DOMString label);
[Throws]
void readAsDataURL(Blob blob);
@ -46,9 +48,3 @@ interface FileReader : EventTarget {
attribute EventHandler onerror;
attribute EventHandler onloadend;
};
// Mozilla extensions.
partial interface FileReader {
[Throws]
void readAsBinaryString(Blob filedata);
};

View File

@ -1,4 +1,4 @@
52366
52368
0/nm
0th/pt
1/n1
@ -39906,6 +39906,7 @@ positive/MYPS
positiveness/M
positivism
positivist/S
positivity/MS
positron/MS
poss
posse/MS
@ -40195,6 +40196,7 @@ prehistoric
prehistorical/Y
prehistory/M
prehuman
preinstall/D
prejudge/LGDS
prejudgement/MS
prejudgment/SM

View File

@ -4,13 +4,14 @@ NULL =
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src util test docs win32
SUBDIRS = src util test docs
EXTRA_DIST = \
autogen.sh \
harfbuzz.doap \
README.python \
BUILD.md \
RELEASING.md \
CMakeLists.txt \
$(NULL)

View File

@ -1,3 +1,38 @@
Overview of changes leading to 1.6.0
Friday, October the 13th, 2017
====================================
- Update to Unicode 10.
- Various Indic and Universal Shaping Engine fixes as a result of
HarfBuzz Hackfest with Jonathan Kew at Web Engines Hackfest at
the Igalia offices in A Coruña, Spain. Thanks Igalia for having
us!
- Implement Unicode Arabic Mark Ordering Algorithm UTR#53.
- Implement optical sizing / tracking in CoreText backend, using
new API hb_font_set_ptem().
- Allow notifying hb_font_t that underlying FT_Face changed sizing,
using new API hb_ft_font_changed().
- More Graphite backend RTL fixes.
- Fix caching of variable font shaping plans.
- hb-view / hb-shape now accept following new arguments:
o --unicodes: takes a list of hex numbers that represent Unicode
codepoints.
New API:
+hb_face_get_table_tags()
+hb_font_set_ptem()
+hb_font_get_ptem()
+hb_ft_font_changed()
Overview of changes leading to 1.5.1
Tuesday, September 5, 2017
====================================

View File

@ -1,9 +1,9 @@
gfx/harfbuzz status as of 2017-09-05:
gfx/harfbuzz status as of 2017-10-13:
This directory contains the harfbuzz source from the 'master' branch of
https://github.com/behdad/harfbuzz.
Current version: 1.5.1
Current version: 1.6.0
UPDATING:

View File

@ -1,6 +1,6 @@
AC_PREREQ([2.64])
AC_INIT([HarfBuzz],
[1.5.1],
[1.6.0],
[https://github.com/behdad/harfbuzz/issues/new],
[harfbuzz],
[http://harfbuzz.org/])
@ -69,8 +69,8 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
])
# Functions and headers
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty)
AC_CHECK_HEADERS(unistd.h sys/mman.h)
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l)
AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h)
# Compiler flags
AC_CANONICAL_HOST
@ -494,8 +494,6 @@ test/fuzzing/Makefile
test/shaping/Makefile
docs/Makefile
docs/version.xml
win32/Makefile
win32/config.h.win32
])
AC_OUTPUT

View File

@ -122,7 +122,7 @@ endif
libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS) $(HBNODISTHEADERS)
libharfbuzz_la_CPPFLAGS = $(HBCFLAGS)
libharfbuzz_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(HB_LIBTOOL_VERSION_INFO) $(export_symbols) -no-undefined
libharfbuzz_la_LDFLAGS = $(AM_LDFLAGS) -lm -version-info $(HB_LIBTOOL_VERSION_INFO) $(export_symbols) -no-undefined
libharfbuzz_la_LIBADD = $(HBLIBS)
EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency)
pkginclude_HEADERS = $(HBHEADERS)
@ -300,6 +300,7 @@ check: harfbuzz.def # For check-defs.sh
dist_check_SCRIPTS = \
check-c-linkage-decls.sh \
check-defs.sh \
check-externs.sh \
check-header-guards.sh \
check-includes.sh \
check-libstdc++.sh \

View File

@ -0,0 +1,21 @@
#!/bin/sh
LC_ALL=C
export LC_ALL
test -z "$srcdir" && srcdir=.
stat=0
test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'`
test "x$EGREP" = x && EGREP='grep -E'
echo 'Checking that all public symbols are exported with HB_EXTERN'
for x in $HBHEADERS; do
test -f "$srcdir/$x" && x="$srcdir/$x"
$EGREP -B1 '^hb_' "$x" | $EGREP -E -v '^(--|hb_|HB_EXTERN )' -A1
done |
grep . >&2 && stat=1
exit $stat

View File

@ -117,6 +117,7 @@ property_names = [
'Top_And_Right',
'Top_And_Left',
'Top_And_Left_And_Right',
'Bottom_And_Left',
'Bottom_And_Right',
'Top_And_Bottom_And_Right',
'Overstruck',
@ -153,7 +154,7 @@ def is_BASE(U, UISC, UGC):
def is_BASE_IND(U, UISC, UGC):
#SPEC-DRAFT return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po)
return (UISC in [Consonant_Dead, Modifying_Letter] or
(UGC == Po and not U in [0x104E, 0x2022]) or
(UGC == Po and not U in [0x104E, 0x2022, 0x11A3F, 0x11A45]) or
False # SPEC-DRAFT-OUTDATED! U == 0x002D
)
def is_BASE_NUM(U, UISC, UGC):
@ -177,6 +178,8 @@ def is_CONS_MOD(U, UISC, UGC):
def is_CONS_SUB(U, UISC, UGC):
#SPEC-DRAFT return UISC == Consonant_Subjoined
return UISC == Consonant_Subjoined and UGC != Lo
def is_CONS_WITH_STACKER(U, UISC, UGC):
return UISC == Consonant_With_Stacker
def is_HALANT(U, UISC, UGC):
return UISC in [Virama, Invisible_Stacker]
def is_HALANT_NUM(U, UISC, UGC):
@ -198,9 +201,7 @@ def is_OTHER(U, UISC, UGC):
def is_Reserved(U, UISC, UGC):
return UGC == 'Cn'
def is_REPHA(U, UISC, UGC):
#return UISC == Consonant_Preceding_Repha
#SPEC-OUTDATED hack to categorize Consonant_With_Stacker and Consonant_Prefixed
return UISC in [Consonant_Preceding_Repha, Consonant_With_Stacker, Consonant_Prefixed]
return UISC in [Consonant_Preceding_Repha, Consonant_Prefixed]
def is_SYM(U, UISC, UGC):
if U == 0x25CC: return False #SPEC-DRAFT
#SPEC-DRAFT return UGC in [So, Sc] or UISC == Symbol_Letter
@ -229,6 +230,7 @@ use_mapping = {
'M': is_CONS_MED,
'CM': is_CONS_MOD,
'SUB': is_CONS_SUB,
'CS': is_CONS_WITH_STACKER,
'H': is_HALANT,
'HN': is_HALANT_NUM,
'ZWNJ': is_ZWNJ,
@ -252,7 +254,7 @@ use_positions = {
},
'M': {
'Abv': [Top],
'Blw': [Bottom],
'Blw': [Bottom, Bottom_And_Left],
'Pst': [Right],
'Pre': [Left],
},
@ -298,8 +300,10 @@ def map_to_use(data):
# the nasalization marks, maybe only for U+1CE9..U+1CF1.
if U == 0x1CED: UISC = Tone_Mark
evals = [(k, v(U,UISC,UGC)) for k,v in items]
values = [k for k,v in evals if v]
# TODO: https://github.com/behdad/harfbuzz/issues/525
if U == 0x1A7F: UISC = Consonant_Final; UIPC = Bottom
values = [k for k,v in items if v(U,UISC,UGC)]
assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values)
USE = values[0]

View File

@ -5,7 +5,7 @@ includedir=/usr/local/include
Name: harfbuzz
Description: HarfBuzz text shaping library ICU integration
Version: 1.5.1
Version: 1.6.0
Requires: harfbuzz
Requires.private: icu-uc

View File

@ -5,9 +5,9 @@ includedir=/usr/local/include
Name: harfbuzz
Description: HarfBuzz text shaping library
Version: 1.5.1
Version: 1.6.0
Libs: -L${libdir} -lharfbuzz
Libs.private:
Libs.private: -lm
Requires.private: glib-2.0 >= 2.19.1
Cflags: -I${includedir}/harfbuzz

View File

@ -8,6 +8,6 @@ Description: HarfBuzz text shaping library
Version: %VERSION%
Libs: -L${libdir} -lharfbuzz
Libs.private: %libs_private%
Libs.private: -lm %libs_private%
Requires.private: %requires_private%
Cflags: -I${includedir}/harfbuzz

View File

@ -128,6 +128,12 @@ hb_blob_create (const char *data,
return blob;
}
static void
_hb_blob_destroy (void *data)
{
hb_blob_destroy ((hb_blob_t *) data);
}
/**
* hb_blob_create_sub_blob:
* @parent: Parent blob.
@ -164,7 +170,7 @@ hb_blob_create_sub_blob (hb_blob_t *parent,
MIN (length, parent->length - offset),
HB_MEMORY_MODE_READONLY,
hb_blob_reference (parent),
(hb_destroy_func_t) hb_blob_destroy);
_hb_blob_destroy);
return blob;
}

View File

@ -504,7 +504,7 @@ typedef enum { /*< flags >*/
} hb_buffer_diff_flags_t;
/* Compare the contents of two buffers, report types of differences. */
hb_buffer_diff_flags_t
HB_EXTERN hb_buffer_diff_flags_t
hb_buffer_diff (hb_buffer_t *buffer,
hb_buffer_t *reference,
hb_codepoint_t dottedcircle_glyph,

View File

@ -32,6 +32,9 @@
#include "hb-object-private.hh"
#include <locale.h>
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
#endif
/* hb_options_t */
@ -246,8 +249,8 @@ struct hb_language_item_t {
static hb_language_item_t *langs;
#ifdef HB_USE_ATEXIT
static
void free_langs (void)
static void
free_langs (void)
{
while (langs) {
hb_language_item_t *next = langs->next;
@ -694,6 +697,48 @@ parse_uint32 (const char **pp, const char *end, uint32_t *pv)
return true;
}
#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
#define USE_XLOCALE 1
#endif
#ifdef USE_XLOCALE
static locale_t C_locale;
#ifdef HB_USE_ATEXIT
static void
free_C_locale (void)
{
if (C_locale)
freelocale (C_locale);
}
#endif
static locale_t
get_C_locale (void)
{
retry:
locale_t C = (locale_t) hb_atomic_ptr_get (&C_locale);
if (unlikely (!C))
{
C = newlocale (LC_ALL_MASK, "C", NULL);
if (!hb_atomic_ptr_cmpexch (&C_locale, NULL, C))
{
freelocale (C_locale);
goto retry;
}
#ifdef HB_USE_ATEXIT
atexit (free_C_locale); /* First person registers atexit() callback. */
#endif
}
return C;
}
#endif
static bool
parse_float (const char **pp, const char *end, float *pv)
{
@ -707,7 +752,11 @@ parse_float (const char **pp, const char *end, float *pv)
float v;
errno = 0;
#ifdef USE_XLOCALE
v = strtod_l (p, &pend, get_C_locale ());
#else
v = strtod (p, &pend);
#endif
if (errno || p == pend)
return false;

View File

@ -43,30 +43,16 @@
# endif /* !__cplusplus */
#endif
#if !defined (HB_DONT_DEFINE_STDINT)
#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \
defined (_sgi) || defined (__sun) || defined (sun) || \
defined (__digital__) || defined (__HP_cc)
# include <inttypes.h>
#elif defined (_AIX)
# include <sys/inttypes.h>
/* VS 2010 (_MSC_VER 1600) has stdint.h */
#elif defined (_MSC_VER) && _MSC_VER < 1600
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
# include <stdint.h>
#endif
#endif
HB_BEGIN_DECLS
@ -321,6 +307,14 @@ typedef enum
/*9.0*/ HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'),
/*9.0*/ HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'),
/*
* Since 1.6.0
*/
/*10.0*/HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'),
/*10.0*/HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'),
/*10.0*/HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'),
/*10.0*/HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'),
/* No script set. */
HB_SCRIPT_INVALID = HB_TAG_NONE,

View File

@ -30,12 +30,27 @@
#include "hb-shaper-impl-private.hh"
#include "hb-coretext.h"
#include <math.h>
#ifndef HB_DEBUG_CORETEXT
#define HB_DEBUG_CORETEXT (HB_DEBUG+0)
#endif
/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
static CGFloat
coretext_font_size (float ptem)
{
/* CoreText points are CSS pixels (96 per inch),
* NOT typographic points (72 per inch).
*
* https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
*/
ptem *= 96.f / 72.f;
return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem;
}
static void
release_table_data (void *user_data)
@ -62,16 +77,22 @@ reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
release_table_data);
}
static void
_hb_cg_font_release (void *data)
{
CGFontRelease ((CGFontRef) data);
}
hb_face_t *
hb_coretext_face_create (CGFontRef cg_font)
{
return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), (hb_destroy_func_t) CGFontRelease);
return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
}
HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face)
HB_SHAPER_DATA_ENSURE_DEFINE(coretext, font)
HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size (font->ptem)) <= .5
)
/*
* shaper face data
@ -113,7 +134,7 @@ static CGFontRef
create_cg_font (hb_face_t *face)
{
CGFontRef cg_font = NULL;
if (face->destroy == (hb_destroy_func_t) CGFontRelease)
if (face->destroy == _hb_cg_font_release)
{
cg_font = CGFontRetain ((CGFontRef) face->user_data);
}
@ -140,7 +161,33 @@ create_cg_font (hb_face_t *face)
static CTFontRef
create_ct_font (CGFontRef cg_font, CGFloat font_size)
{
CTFontRef ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL);
CTFontRef ct_font = NULL;
/* CoreText does not enable trak table usage / tracking when creating a CTFont
* using CTFontCreateWithGraphicsFont. The only way of enabling tracking seems
* to be through the CTFontCreateUIFontForLanguage call. */
CFStringRef cg_postscript_name = CGFontCopyPostScriptName (cg_font);
if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) ||
CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay")))
{
CTFontUIFontType font_type = kCTFontUIFontSystem;
if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold")))
font_type = kCTFontUIFontEmphasizedSystem;
ct_font = CTFontCreateUIFontForLanguage (font_type, font_size, NULL);
CFStringRef ct_result_name = CTFontCopyPostScriptName(ct_font);
if (CFStringCompare (ct_result_name, cg_postscript_name, 0) != kCFCompareEqualTo)
{
CFRelease(ct_font);
ct_font = NULL;
}
CFRelease (ct_result_name);
}
CFRelease (cg_postscript_name);
if (!ct_font)
ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL);
if (unlikely (!ct_font)) {
DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed");
return NULL;
@ -202,51 +249,24 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
return ct_font;
}
struct hb_coretext_shaper_face_data_t {
CGFontRef cg_font;
CTFontRef ct_font;
};
hb_coretext_shaper_face_data_t *
_hb_coretext_shaper_face_data_create (hb_face_t *face)
{
hb_coretext_shaper_face_data_t *data = (hb_coretext_shaper_face_data_t *) calloc (1, sizeof (hb_coretext_shaper_face_data_t));
if (unlikely (!data))
return NULL;
CGFontRef cg_font = create_cg_font (face);
data->cg_font = create_cg_font (face);
if (unlikely (!data->cg_font))
if (unlikely (!cg_font))
{
DEBUG_MSG (CORETEXT, face, "CGFont creation failed..");
free (data);
return NULL;
}
/* We use 36pt size instead of UPEM, because CoreText implements the 'trak' table,
* which can make the font too tight at large sizes. 36pt should be a good semi-neutral
* size.
*
* Since we always create CTFont at a fixed size, our CTFont lives in face_data
* instead of font_data. Which is good, because when people change scale on
* hb_font_t, we won't need to update our CTFont. */
data->ct_font = create_ct_font (data->cg_font, 36.);
if (unlikely (!data->ct_font))
{
DEBUG_MSG (CORETEXT, face, "CTFont creation failed.");
CFRelease (data->cg_font);
free (data);
return NULL;
}
return data;
return (hb_coretext_shaper_face_data_t *) cg_font;
}
void
_hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
{
CFRelease (data->ct_font);
CFRelease (data->cg_font);
free (data);
CFRelease ((CGFontRef) data);
}
/*
@ -256,8 +276,7 @@ CGFontRef
hb_coretext_face_get_cg_font (hb_face_t *face)
{
if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
return face_data->cg_font;
return (CGFontRef) HB_SHAPER_DATA_GET (face);
}
@ -265,17 +284,28 @@ hb_coretext_face_get_cg_font (hb_face_t *face)
* shaper font data
*/
struct hb_coretext_shaper_font_data_t {};
hb_coretext_shaper_font_data_t *
_hb_coretext_shaper_font_data_create (hb_font_t *font HB_UNUSED)
_hb_coretext_shaper_font_data_create (hb_font_t *font)
{
return (hb_coretext_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
hb_face_t *face = font->face;
if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size (font->ptem));
if (unlikely (!ct_font))
{
DEBUG_MSG (CORETEXT, font, "CGFont creation failed..");
return NULL;
}
return (hb_coretext_shaper_font_data_t *) ct_font;
}
void
_hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
{
CFRelease ((CTFontRef) data);
}
@ -303,10 +333,8 @@ _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_
CTFontRef
hb_coretext_font_get_ct_font (hb_font_t *font)
{
hb_face_t *face = font->face;
if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
return face_data->ct_font;
if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return NULL;
return (CTFontRef)HB_SHAPER_DATA_GET (font);
}
@ -538,9 +566,10 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
unsigned int num_features)
{
hb_face_t *face = font->face;
hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
CTFontRef ct_font = (CTFontRef) HB_SHAPER_DATA_GET (font);
CGFloat ct_font_size = CTFontGetSize (face_data->ct_font);
CGFloat ct_font_size = CTFontGetSize (ct_font);
CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
@ -675,7 +704,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
CFRelease (attributes);
range->font = CTFontCreateCopyWithAttributes (face_data->ct_font, 0.0, NULL, font_desc);
range->font = CTFontCreateCopyWithAttributes (ct_font, 0.0, NULL, font_desc);
CFRelease (font_desc);
}
else
@ -829,7 +858,7 @@ resize_and_retry:
CFRelease (lang);
}
CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
kCTFontAttributeName, face_data->ct_font);
kCTFontAttributeName, ct_font);
if (num_features && range_records.len)
{
@ -947,7 +976,7 @@ resize_and_retry:
*/
CFDictionaryRef attributes = CTRunGetAttributes (run);
CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
if (!CFEqual (run_ct_font, face_data->ct_font))
if (!CFEqual (run_ct_font, ct_font))
{
/* The run doesn't use our main font instance. We have to figure out
* whether font fallback happened, or this is just CoreText giving us
@ -985,13 +1014,13 @@ resize_and_retry:
CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
if (run_cg_font)
{
matched = CFEqual (run_cg_font, face_data->cg_font);
matched = CFEqual (run_cg_font, cg_font);
CFRelease (run_cg_font);
}
}
if (!matched)
{
CFStringRef font_ps_name = CTFontCopyName (face_data->ct_font, kCTFontPostScriptNameKey);
CFStringRef font_ps_name = CTFontCopyName (ct_font, kCTFontPostScriptNameKey);
CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScriptNameKey);
CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name, 0);
CFRelease (run_ps_name);
@ -1263,22 +1292,20 @@ struct hb_coretext_aat_shaper_face_data_t {};
hb_coretext_aat_shaper_face_data_t *
_hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
{
hb_blob_t *mort_blob = face->reference_table (HB_CORETEXT_TAG_MORT);
/* Umm, we just reference the table to check whether it exists.
* Maybe add better API for this? */
if (!hb_blob_get_length (mort_blob))
{
hb_blob_destroy (mort_blob);
mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX);
if (!hb_blob_get_length (mort_blob))
{
hb_blob_destroy (mort_blob);
return NULL;
}
}
hb_blob_destroy (mort_blob);
static const hb_tag_t tags[] = {HB_CORETEXT_TAG_MORX, HB_CORETEXT_TAG_MORT, HB_CORETEXT_TAG_KERX};
return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
for (unsigned int i = 0; i < ARRAY_LENGTH (tags); i++)
{
hb_blob_t *blob = face->reference_table (tags[i]);
if (hb_blob_get_length (blob))
{
hb_blob_destroy (blob);
return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
}
hb_blob_destroy (blob);
}
return NULL;
}
void

View File

@ -42,6 +42,7 @@ HB_BEGIN_DECLS
#define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t')
#define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
#define HB_CORETEXT_TAG_KERX HB_TAG('k','e','r','x')
HB_EXTERN hb_face_t *

View File

@ -54,13 +54,6 @@ struct hb_face_t {
mutable unsigned int upem; /* Units-per-EM. */
mutable unsigned int num_glyphs; /* Number of glyphs. */
enum dirty_t {
DIRTY_NOTHING = 0x0000,
DIRTY_INDEX = 0x0001,
DIRTY_UPEM = 0x0002,
DIRTY_NUM_GLYPHS = 0x0004,
} dirty;
struct hb_shaper_data_t shaper_data; /* Various shaper data. */
/* Various non-shaping data. */
@ -106,8 +99,6 @@ struct hb_face_t {
HB_INTERNAL void load_num_glyphs (void) const;
};
HB_MARK_AS_FLAG_T (hb_face_t::dirty_t);
extern HB_INTERNAL const hb_face_t _hb_face_nil;
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS

View File

@ -51,8 +51,6 @@ const hb_face_t _hb_face_nil = {
1000, /* upem */
0, /* num_glyphs */
hb_face_t::DIRTY_NOTHING, /* dirty */
{
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
#include "hb-shaper-list.hh"
@ -120,8 +118,10 @@ _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
}
static void
_hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure)
_hb_face_for_data_closure_destroy (void *data)
{
hb_face_for_data_closure_t *closure = (hb_face_for_data_closure_t *) data;
hb_blob_destroy (closure->blob);
free (closure);
}
@ -171,7 +171,7 @@ hb_face_create (hb_blob_t *blob,
face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
closure,
(hb_destroy_func_t) _hb_face_for_data_closure_destroy);
_hb_face_for_data_closure_destroy);
face->index = index;
@ -367,11 +367,6 @@ hb_face_set_index (hb_face_t *face,
if (face->immutable)
return;
if (face->index == index)
return;
face->dirty |= face->DIRTY_INDEX;
face->index = index;
}
@ -407,11 +402,6 @@ hb_face_set_upem (hb_face_t *face,
if (face->immutable)
return;
if (face->upem == upem)
return;
face->dirty |= face->DIRTY_UPEM;
face->upem = upem;
}
@ -456,11 +446,6 @@ hb_face_set_glyph_count (hb_face_t *face,
if (face->immutable)
return;
if (face->num_glyphs == glyph_count)
return;
face->dirty |= face->DIRTY_NUM_GLYPHS;
face->num_glyphs = glyph_count;
}
@ -489,4 +474,33 @@ hb_face_t::load_num_glyphs (void) const
hb_blob_destroy (maxp_blob);
}
/**
* hb_face_get_table_tags:
* @face: a face.
*
* Retrieves table tags for a face, if possible.
*
* Return value: total number of tables, or 0 if not possible to list.
*
* Since: 1.6.0
**/
unsigned int
hb_face_get_table_tags (hb_face_t *face,
unsigned int start_offset,
unsigned int *table_count, /* IN/OUT */
hb_tag_t *table_tags /* OUT */)
{
if (face->destroy != _hb_face_for_data_closure_destroy)
{
if (table_count)
*table_count = 0;
return 0;
}
hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data;
const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob);
const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
return ot_face.get_table_tags (start_offset, table_count, table_tags);
}

View File

@ -111,6 +111,11 @@ hb_face_set_glyph_count (hb_face_t *face,
HB_EXTERN unsigned int
hb_face_get_glyph_count (hb_face_t *face);
HB_EXTERN unsigned int
hb_face_get_table_tags (hb_face_t *face,
unsigned int start_offset,
unsigned int *table_count, /* IN/OUT */
hb_tag_t *table_tags /* OUT */);
HB_END_DECLS

View File

@ -108,6 +108,8 @@ struct hb_font_t {
unsigned int x_ppem;
unsigned int y_ppem;
float ptem;
/* Font variation coordinates. */
unsigned int num_coords;
int *coords;
@ -116,16 +118,6 @@ struct hb_font_t {
void *user_data;
hb_destroy_func_t destroy;
enum dirty_t {
DIRTY_NOTHING = 0x0000,
DIRTY_FACE = 0x0001,
DIRTY_PARENT = 0x0002,
DIRTY_FUNCS = 0x0004,
DIRTY_SCALE = 0x0008,
DIRTY_PPEM = 0x0010,
DIRTY_VARIATIONS = 0x0020,
} dirty;
struct hb_shaper_data_t shaper_data;
@ -553,8 +545,6 @@ struct hb_font_t {
}
};
HB_MARK_AS_FLAG_T (hb_font_t::dirty_t);
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
#include "hb-shaper-list.hh"

View File

@ -1157,8 +1157,20 @@ hb_font_create_sub_font (hb_font_t *parent)
font->y_scale = parent->y_scale;
font->x_ppem = parent->x_ppem;
font->y_ppem = parent->y_ppem;
font->ptem = parent->ptem;
/* TODO: copy variation coordinates. */
font->num_coords = parent->num_coords;
if (!font->num_coords)
font->coords = NULL;
else
{
unsigned int size = parent->num_coords * sizeof (parent->coords[0]);
font->coords = (int *) malloc (size);
if (unlikely (!font->coords))
font->num_coords = 0;
else
memcpy (font->coords, parent->coords, size);
}
return font;
}
@ -1188,6 +1200,7 @@ hb_font_get_empty (void)
0, /* x_ppem */
0, /* y_ppem */
0, /* ptem */
0, /* num_coords */
NULL, /* coords */
@ -1196,8 +1209,6 @@ hb_font_get_empty (void)
NULL, /* user_data */
NULL, /* destroy */
hb_font_t::DIRTY_NOTHING, /* dirty */
{
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
#include "hb-shaper-list.hh"
@ -1350,11 +1361,6 @@ hb_font_set_parent (hb_font_t *font,
if (!parent)
parent = hb_font_get_empty ();
if (parent == font->parent)
return;
font->dirty |= font->DIRTY_PARENT;
hb_font_t *old = font->parent;
font->parent = hb_font_reference (parent);
@ -1397,11 +1403,6 @@ hb_font_set_face (hb_font_t *font,
if (unlikely (!face))
face = hb_face_get_empty ();
if (font->face == face)
return;
font->dirty |= font->DIRTY_FACE;
hb_face_t *old = font->face;
font->face = hb_face_reference (face);
@ -1455,8 +1456,6 @@ hb_font_set_funcs (hb_font_t *font,
if (!klass)
klass = hb_font_funcs_get_empty ();
font->dirty |= font->DIRTY_FUNCS;
hb_font_funcs_reference (klass);
hb_font_funcs_destroy (font->klass);
font->klass = klass;
@ -1512,11 +1511,6 @@ hb_font_set_scale (hb_font_t *font,
if (font->immutable)
return;
if (font->x_scale == x_scale && font->y_scale == y_scale)
return;
font->dirty |= font->DIRTY_SCALE;
font->x_scale = x_scale;
font->y_scale = y_scale;
}
@ -1558,11 +1552,6 @@ hb_font_set_ppem (hb_font_t *font,
if (font->immutable)
return;
if (font->x_ppem == x_ppem && font->y_ppem == y_ppem)
return;
font->dirty |= font->DIRTY_PPEM;
font->x_ppem = x_ppem;
font->y_ppem = y_ppem;
}
@ -1586,6 +1575,40 @@ hb_font_get_ppem (hb_font_t *font,
if (y_ppem) *y_ppem = font->y_ppem;
}
/**
* hb_font_set_ptem:
* @font: a font.
* @ptem:
*
* Sets "point size" of the font.
*
* Since: 1.6.0
**/
void
hb_font_set_ptem (hb_font_t *font, float ptem)
{
if (font->immutable)
return;
font->ptem = ptem;
}
/**
* hb_font_get_ptem:
* @font: a font.
*
* Gets the "point size" of the font. A value of 0 means unset.
*
* Return value: Point size.
*
* Since: 0.9.2
**/
float
hb_font_get_ptem (hb_font_t *font)
{
return font->ptem;
}
/*
* Variations
*/
@ -1595,16 +1618,6 @@ _hb_font_adopt_var_coords_normalized (hb_font_t *font,
int *coords, /* 2.14 normalized */
unsigned int coords_length)
{
if (font->num_coords == coords_length &&
(coords_length == 0 ||
0 == memcmp (font->coords, coords, coords_length * sizeof (coords[0]))))
{
free (coords);
return;
}
font->dirty |= font->DIRTY_VARIATIONS;
free (font->coords);
font->coords = coords;

View File

@ -607,6 +607,16 @@ hb_font_get_ppem (hb_font_t *font,
unsigned int *x_ppem,
unsigned int *y_ppem);
/*
* Point size per EM. Used for optical-sizing in CoreText.
* A value of zero means "not set".
*/
HB_EXTERN void
hb_font_set_ptem (hb_font_t *font, float ptem);
HB_EXTERN float
hb_font_get_ptem (hb_font_t *font);
HB_EXTERN void
hb_font_set_variations (hb_font_t *font,
const hb_variation_t *variations,

View File

@ -95,14 +95,16 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
}
static void
_hb_ft_face_destroy (FT_Face ft_face)
_hb_ft_face_destroy (void *data)
{
FT_Done_Face (ft_face);
FT_Done_Face ((FT_Face) data);
}
static void
_hb_ft_font_destroy (hb_ft_font_t *ft_font)
_hb_ft_font_destroy (void *data)
{
hb_ft_font_t *ft_font = (hb_ft_font_t *) data;
if (ft_font->unref)
_hb_ft_face_destroy (ft_font->ft_face);
@ -124,7 +126,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
if (font->immutable)
return;
if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
if (font->destroy != _hb_ft_font_destroy)
return;
hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
@ -144,7 +146,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
int
hb_ft_font_get_load_flags (hb_font_t *font)
{
if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
if (font->destroy != _hb_ft_font_destroy)
return 0;
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
@ -155,7 +157,7 @@ hb_ft_font_get_load_flags (hb_font_t *font)
FT_Face
hb_ft_font_get_face (hb_font_t *font)
{
if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
if (font->destroy != _hb_ft_font_destroy)
return NULL;
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
@ -474,7 +476,7 @@ retry:
hb_font_set_funcs (font,
funcs,
_hb_ft_font_create (ft_face, symbol, unref),
(hb_destroy_func_t) _hb_ft_font_destroy);
_hb_ft_font_destroy);
}
@ -553,7 +555,7 @@ hb_face_t *
hb_ft_face_create_referenced (FT_Face ft_face)
{
FT_Reference_Face (ft_face);
return hb_ft_face_create (ft_face, (hb_destroy_func_t) _hb_ft_face_destroy);
return hb_ft_face_create (ft_face, _hb_ft_face_destroy);
}
static void
@ -608,6 +610,19 @@ hb_ft_font_create (FT_Face ft_face,
font = hb_font_create (face);
hb_face_destroy (face);
_hb_ft_font_set_funcs (font, ft_face, false);
hb_ft_font_changed (font);
return font;
}
void
hb_ft_font_changed (hb_font_t *font)
{
if (font->destroy != _hb_ft_font_destroy)
return;
hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
FT_Face ft_face = ft_font->ft_face;
hb_font_set_scale (font,
(int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1u<<15)) >> 16),
(int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1u<<15)) >> 16));
@ -638,8 +653,6 @@ hb_ft_font_create (FT_Face ft_face,
free (mm_var);
}
#endif
return font;
}
/**
@ -655,7 +668,7 @@ hb_font_t *
hb_ft_font_create_referenced (FT_Face ft_face)
{
FT_Reference_Face (ft_face);
return hb_ft_font_create (ft_face, (hb_destroy_func_t) _hb_ft_face_destroy);
return hb_ft_font_create (ft_face, _hb_ft_face_destroy);
}

View File

@ -116,7 +116,13 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags);
HB_EXTERN int
hb_ft_font_get_load_flags (hb_font_t *font);
/* Makes an hb_font_t use FreeType internally to implement font functions. */
/* Call when size or variations settings on underlying FT_Face change. */
HB_EXTERN void
hb_ft_font_changed (hb_font_t *font);
/* Makes an hb_font_t use FreeType internally to implement font functions.
* Note: this internally creates an FT_Face. Use it when you create your
* hb_face_t using hb_face_create(). */
HB_EXTERN void
hb_ft_font_set_funcs (hb_font_t *font);

View File

@ -383,6 +383,13 @@ hb_glib_get_unicode_funcs (void)
}
#if GLIB_CHECK_VERSION(2,31,10)
static void
_hb_g_bytes_unref (void *data)
{
g_bytes_unref ((GBytes *) data);
}
/**
* hb_glib_blob_create:
*
@ -397,6 +404,6 @@ hb_glib_blob_create (GBytes *gbytes)
size,
HB_MEMORY_MODE_READONLY,
g_bytes_ref (gbytes),
(hb_destroy_func_t) g_bytes_unref);
_hb_g_bytes_unref);
}
#endif

View File

@ -389,7 +389,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
}
else
{
curradvx = gr_seg_advance_X(seg);
curradvx = gr_seg_advance_X(seg) * xscale;
for (is = gr_seg_first_slot (seg); is; pPos++, info++, is = gr_slot_next_in_segment (is))
{
if (info->cluster != currclus)

View File

@ -79,6 +79,24 @@ typedef struct OffsetTable
if (unlikely (i >= numTables)) return Null(TableRecord);
return tables[i];
}
inline unsigned int get_table_tags (unsigned int start_offset,
unsigned int *table_count, /* IN/OUT */
hb_tag_t *table_tags /* OUT */) const
{
if (table_count)
{
if (start_offset >= numTables)
*table_count = 0;
else
*table_count = MIN (*table_count, numTables - start_offset);
const TableRecord *sub_tables = tables + start_offset;
unsigned int count = *table_count;
for (unsigned int i = 0; i < count; i++)
table_tags[i] = sub_tables[i].tag;
}
return numTables;
}
inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
{
Tag t;

View File

@ -458,8 +458,10 @@ _hb_ot_font_create (hb_face_t *face)
}
static void
_hb_ot_font_destroy (hb_ot_font_t *ot_font)
_hb_ot_font_destroy (void *data)
{
hb_ot_font_t *ot_font = (hb_ot_font_t *) data;
ot_font->cmap.fini ();
ot_font->h_metrics.fini ();
ot_font->v_metrics.fini ();
@ -627,5 +629,5 @@ hb_ot_font_set_funcs (hb_font_t *font)
hb_font_set_funcs (font,
_hb_ot_get_font_funcs (),
ot_font,
(hb_destroy_func_t) _hb_ot_font_destroy);
_hb_ot_font_destroy);
}

View File

@ -1087,7 +1087,9 @@ struct MarkBasePosFormat1
do {
if (!skippy_iter.prev ()) return_trace (false);
/* We only want to attach to the first of a MultipleSubst sequence. Reject others. */
if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break;
if (!_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx]) ||
0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]))
break;
skippy_iter.reject ();
} while (1);

View File

@ -374,6 +374,13 @@ struct hb_apply_context_t :
inline void reject (void) { num_items++; match_glyph_data--; }
inline matcher_t::may_skip_t
may_skip (const hb_apply_context_t *c,
const hb_glyph_info_t &info) const
{
return matcher.may_skip (c, info);
}
inline bool next (void)
{
assert (num_items > 0);
@ -736,11 +743,17 @@ static inline bool match_input (hb_apply_context_t *c,
* - Ligatures cannot be formed across glyphs attached to different components
* of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and
* LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother.
* However, it would be wrong to ligate that SHADDA,FATHA sequence.o
* There is an exception to this: If a ligature tries ligating with marks that
* belong to it itself, go ahead, assuming that the font designer knows what
* they are doing (otherwise it can break Indic stuff when a matra wants to
* ligate with a conjunct...)
* However, it would be wrong to ligate that SHADDA,FATHA sequence.
* There are a couple of exceptions to this:
*
* o If a ligature tries ligating with marks that belong to it itself, go ahead,
* assuming that the font designer knows what they are doing (otherwise it can
* break Indic stuff when a matra wants to ligate with a conjunct,
*
* o If two marks want to ligate and they belong to different components of the
* same ligature glyph, and said ligature glyph is to be ignored according to
* mark-filtering rules, then allow.
* https://github.com/behdad/harfbuzz/issues/545
*/
bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
@ -751,6 +764,12 @@ static inline bool match_input (hb_apply_context_t *c,
unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
enum {
LIGBASE_NOT_CHECKED,
LIGBASE_MAY_NOT_SKIP,
LIGBASE_MAY_SKIP
} ligbase = LIGBASE_NOT_CHECKED;
match_positions[0] = buffer->idx;
for (unsigned int i = 1; i < count; i++)
{
@ -761,13 +780,43 @@ static inline bool match_input (hb_apply_context_t *c,
unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]);
unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]);
if (first_lig_id && first_lig_comp) {
if (first_lig_id && first_lig_comp)
{
/* If first component was attached to a previous ligature component,
* all subsequent components should be attached to the same ligature
* component, otherwise we shouldn't ligate them. */
* component, otherwise we shouldn't ligate them... */
if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
return_trace (false);
} else {
{
/* ...unless, we are attached to a base ligature and that base
* ligature is ignorable. */
if (ligbase == LIGBASE_NOT_CHECKED)
{
bool found = false;
const hb_glyph_info_t *out = buffer->out_info;
unsigned int j = buffer->out_len;
while (j && _hb_glyph_info_get_lig_id (&out[j - 1]) == first_lig_id)
{
if (_hb_glyph_info_get_lig_comp (&out[j - 1]) == 0)
{
j--;
found = true;
break;
}
j--;
}
if (found && skippy_iter.may_skip (c, out[j]) == hb_apply_context_t::matcher_t::SKIP_YES)
ligbase = LIGBASE_MAY_SKIP;
else
ligbase = LIGBASE_MAY_NOT_SKIP;
}
if (ligbase == LIGBASE_MAY_NOT_SKIP)
return_trace (false);
}
}
else
{
/* If first component was NOT attached to a previous ligature component,
* all subsequent components should also NOT be attached to any ligature
* component, unless they are attached to the first component itself! */

View File

@ -347,6 +347,8 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0;
}
#define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info)))
static inline bool
_hb_glyph_info_is_unicode_space (const hb_glyph_info_t *info)
{

View File

@ -6,10 +6,10 @@
*
* on files with these headers:
*
* # ArabicShaping-9.0.0.txt
* # Date: 2016-02-24, 22:25:00 GMT [RP]
* # Blocks-9.0.0.txt
* # Date: 2016-02-05, 23:48:00 GMT [KW]
* # ArabicShaping-10.0.0.txt
* # Date: 2017-02-16, 00:00:00 GMT [RP, KW]
* # Blocks-10.0.0.txt
* # Date: 2017-04-12, 17:30:00 GMT [KW]
* UnicodeData.txt does not have a header.
*/
@ -72,7 +72,10 @@ static const uint8_t joining_table[] =
/* Mandaic */
/* 0840 */ R,D,D,D,D,D,R,R,D,R,D,D,D,D,D,D,D,D,D,D,R,D,U,U,U,X,X,X,X,X,X,X,
/* 0860 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Syriac Supplement */
/* 0860 */ D,U,D,D,D,D,U,R,D,R,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* 0880 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Arabic Extended-A */
@ -130,7 +133,7 @@ static const uint8_t joining_table[] =
/* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
/* 1E940 */ D,D,D,D,
}; /* Table items: 1214; occupancy: 54% */
}; /* Table items: 1214; occupancy: 55% */
static unsigned int

View File

@ -613,6 +613,80 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan,
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}
/* http://www.unicode.org/reports/tr53/tr53-1.pdf */
static hb_codepoint_t
modifier_combining_marks[] =
{
0x0654u, /* ARABIC HAMZA ABOVE */
0x0655u, /* ARABIC HAMZA BELOW */
0x0658u, /* ARABIC MARK NOON GHUNNA */
0x06DCu, /* ARABIC SMALL HIGH SEEN */
0x06E3u, /* ARABIC SMALL LOW SEEN */
0x06E7u, /* ARABIC SMALL HIGH YEH */
0x06E8u, /* ARABIC SMALL HIGH NOON */
0x08F3u, /* ARABIC SMALL HIGH WAW */
};
static inline bool
info_is_mcm (const hb_glyph_info_t &info)
{
hb_codepoint_t u = info.codepoint;
for (unsigned int i = 0; i < ARRAY_LENGTH (modifier_combining_marks); i++)
if (u == modifier_combining_marks[i])
return true;
return false;
}
static void
reorder_marks_arabic (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
unsigned int start,
unsigned int end)
{
hb_glyph_info_t *info = buffer->info;
unsigned int i = start;
for (unsigned int cc = 220; cc <= 230; cc += 10)
{
DEBUG_MSG (ARABIC, buffer, "Looking for %d's starting at %d\n", cc, i);
while (i < end && info_cc(info[i]) < cc)
i++;
DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d\n", cc, i);
if (i == end)
break;
if (info_cc(info[i]) > cc)
continue;
/* Technically we should also check "info_cc(info[j]) == cc"
* in the following loop. But not doing it is safe; we might
* end up moving all the 220 MCMs and 230 MCMs together in one
* move and be done. */
unsigned int j = i;
while (j < end && info_is_mcm (info[j]))
j++;
DEBUG_MSG (ARABIC, buffer, "Found %d's from %d to %d\n", cc, i, j);
if (i == j)
continue;
/* Shift it! */
DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d\n", cc, i, j);
hb_glyph_info_t temp[HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS];
assert (j - i <= ARRAY_LENGTH (temp));
buffer->merge_clusters (start, j);
memmove (temp, &info[i], (j - i) * sizeof (hb_glyph_info_t));
memmove (&info[start + j - i], &info[start], (i - start) * sizeof (hb_glyph_info_t));
memmove (&info[start], temp, (j - i) * sizeof (hb_glyph_info_t));
start += j - i;
i = j;
}
}
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
{
"arabic",
@ -627,6 +701,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
NULL, /* compose */
setup_masks_arabic,
NULL, /* disable_otl */
reorder_marks_arabic,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};

View File

@ -41,6 +41,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
NULL, /* compose */
NULL, /* setup_masks */
NULL, /* disable_otl */
NULL, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};

View File

@ -426,6 +426,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
NULL, /* compose */
setup_masks_hangul,
NULL, /* disable_otl */
NULL, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};

View File

@ -181,6 +181,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
compose_hebrew,
NULL, /* setup_masks */
disable_otl_hebrew,
NULL, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};

File diff suppressed because it is too large Load Diff

View File

@ -57,6 +57,7 @@ Repha = 15;
Ra = 16;
CM = 17;
Symbol= 18;
CS = 19;
c = (C | Ra); # is_consonant
n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier
@ -76,9 +77,9 @@ medial_group = CM?;
halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4}) (Coeng (cn|V))?;
consonant_syllable = Repha? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail;
consonant_syllable = (Repha|CS)? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail;
vowel_syllable = reph? V.n? (ZWJ | (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail);
standalone_cluster = (Repha? PLACEHOLDER | reph? DOTTEDCIRCLE).n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
standalone_cluster = ((Repha|CS)? PLACEHOLDER | reph? DOTTEDCIRCLE).n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
symbol_cluster = symbol syllable_tail;
broken_cluster = reph? n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
other = any;

View File

@ -60,7 +60,8 @@ enum indic_category_t {
OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
OT_Ra = 16,
OT_CM = 17, /* Consonant-Medial. */
OT_Symbol = 18 /* Avagraha, etc that take marks (SM,A,VD). */
OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */
OT_CS = 19
};
#define MEDIAL_FLAGS (FLAG (OT_CM))
@ -70,7 +71,7 @@ enum indic_category_t {
* We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
* cannot happen in a consonant syllable. The plus side however is, we can call the
* consonant syllable logic from the vowel syllable function and get it all right! */
#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CS) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng))
@ -121,8 +122,8 @@ enum indic_syllabic_category_t {
INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED = OT_X, /* Don't care. */
INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM,
INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA = OT_N,
INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER = OT_C,
INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM,
INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER = OT_CS,
INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM, /* https://github.com/behdad/harfbuzz/issues/552 */
INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER = OT_Coeng,
INDIC_SYLLABIC_CATEGORY_JOINER = OT_ZWJ,
INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,

View File

@ -6,61 +6,62 @@
*
* on files with these headers:
*
* # IndicSyllabicCategory-9.0.0.txt
* # Date: 2016-05-21, 02:46:00 GMT [RP]
* # IndicPositionalCategory-9.0.0.txt
* # Date: 2016-02-25, 00:48:00 GMT [RP]
* # Blocks-9.0.0.txt
* # Date: 2016-02-05, 23:48:00 GMT [KW]
* # IndicSyllabicCategory-10.0.0.txt
* # Date: 2017-05-31, 01:07:00 GMT [KW, RP]
* # IndicPositionalCategory-10.0.0.txt
* # Date: 2017-05-31, 01:07:00 GMT [RP]
* # Blocks-10.0.0.txt
* # Date: 2017-04-12, 17:30:00 GMT [KW]
*/
#include "hb-ot-shape-complex-indic-private.hh"
#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 15 chars; Avagraha */
#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 67 chars; Bindu */
#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 80 chars; Bindu */
#define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */
#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 53 chars; Cantillation_Mark */
#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 1907 chars; Consonant */
#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 57 chars; Cantillation_Mark */
#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2024 chars; Consonant */
#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 10 chars; Consonant_Dead */
#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 62 chars; Consonant_Final */
#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 68 chars; Consonant_Final */
#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */
#define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */
#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 22 chars; Consonant_Medial */
#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 16 chars; Consonant_Placeholder */
#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 1 chars; Consonant_Preceding_Repha */
#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 2 chars; Consonant_Prefixed */
#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 90 chars; Consonant_Subjoined */
#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */
#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 27 chars; Consonant_Medial */
#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 18 chars; Consonant_Placeholder */
#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 2 chars; Consonant_Preceding_Repha */
#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 7 chars; Consonant_Prefixed */
#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 95 chars; Consonant_Subjoined */
#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 5 chars; Consonant_Succeeding_Repha */
#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 4 chars; Consonant_With_Stacker */
#define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 2 chars; Gemination_Mark */
#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 7 chars; Invisible_Stacker */
#define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 3 chars; Gemination_Mark */
#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 10 chars; Invisible_Stacker */
#define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */
#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */
#define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */
#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 24 chars; Nukta */
#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 459 chars; Number */
#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 28 chars; Nukta */
#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 469 chars; Number */
#define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */
#define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */
#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 16 chars; Pure_Killer */
#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 21 chars; Pure_Killer */
#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */
#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 22 chars; Syllable_Modifier */
#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */
#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 42 chars; Tone_Mark */
#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 24 chars; Virama */
#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 31 chars; Visarga */
#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 34 chars; Visarga */
#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */
#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 602 chars; Vowel_Dependent */
#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 431 chars; Vowel_Independent */
#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 633 chars; Vowel_Dependent */
#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 443 chars; Vowel_Independent */
#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 300 chars; Bottom */
#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 330 chars; Bottom */
#define IMC_BL INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT /* 1 chars; Bottom_And_Left */
#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */
#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 57 chars; Left */
#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 21 chars; Left_And_Right */
#define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */
#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */
#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 258 chars; Right */
#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 342 chars; Top */
#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 262 chars; Right */
#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 380 chars; Top */
#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */
#define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */
#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */
@ -133,7 +134,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* 09E0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
/* 09E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
/* 09F0 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
/* 09F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
/* 09F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(Bi,x), _(x,x), _(x,x), _(x,x),
/* Gurmukhi */
@ -171,7 +172,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* 0AE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
/* 0AE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
/* 0AF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
/* 0AF8 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
/* 0AF8 */ _(x,x), _(C,x), _(Ca,T), _(Ca,T), _(Ca,T), _(N,T), _(N,T), _(N,T),
/* Oriya */
@ -251,14 +252,14 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* Malayalam */
/* 0D00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
/* 0D00 */ _(Bi,T), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
/* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
/* 0D10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
/* 0D18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
/* 0D20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
/* 0D28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
/* 0D30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
/* 0D38 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(A,x), _(M,R), _(M,R),
/* 0D38 */ _(C,x), _(C,x), _(C,x), _(PK,T), _(PK,T), _(A,x), _(M,R), _(M,R),
/* 0D40 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(x,x), _(M,L), _(M,L),
/* 0D48 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T),_(CPR,x), _(x,x),
/* 0D50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(M,R),
@ -341,7 +342,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* 1CD8 */ _(Ca,B), _(Ca,B), _(Ca,T), _(Ca,T), _(Ca,B), _(Ca,B), _(Ca,B), _(Ca,B),
/* 1CE0 */ _(Ca,T), _(Ca,R), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O),
/* 1CE8 */ _(x,O), _(x,x), _(x,x), _(x,x), _(x,x), _(x,B), _(x,x), _(x,x),
/* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(Ca,T), _(x,x), _(x,x), _(x,x),
/* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(Ca,T), _(x,x), _(x,x), _(Ca,R),
/* 1CF8 */ _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
#define indic_offset_0x2008u 1656
@ -368,7 +369,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* A8E0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
/* A8E8 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
/* A8F0 */ _(Ca,T), _(Ca,T), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
/* A8F0 */ _(Ca,T), _(Ca,T), _(Bi,x), _(Bi,x), _(x,x), _(x,x), _(x,x), _(x,x),
#define indic_offset_0xa9e0u 1720
@ -390,7 +391,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(CP,x), _(CP,x), _(CP,x), _(x,x),
/* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,R), _(TM,T), _(TM,R), _(C,x), _(C,x),
}; /* Table items: 1784; occupancy: 69% */
}; /* Table items: 1784; occupancy: 70% */
INDIC_TABLE_ELEMENT_TYPE
hb_indic_get_categories (hb_codepoint_t u)
@ -422,13 +423,6 @@ hb_indic_get_categories (hb_codepoint_t u)
if (hb_in_range<hb_codepoint_t> (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u];
break;
case 0x11u:
// According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil,
// so the Indic shaper needs to know their categories.
if (unlikely (u == 0x11303)) return _(Vs,R);
if (unlikely (u == 0x1133c)) return _(N,B);
break;
default:
break;
}
@ -474,6 +468,7 @@ hb_indic_get_categories (hb_codepoint_t u)
#undef ISC_VI
#undef IMC_B
#undef IMC_BL
#undef IMC_BR
#undef IMC_L
#undef IMC_LR

View File

@ -208,7 +208,21 @@ set_indic_properties (hb_glyph_info_t &info)
cat = OT_M;
pos = POS_ABOVE_C;
}
else if (unlikely (u == 0x0A51u))
{
/* https://github.com/behdad/harfbuzz/issues/524 */
cat = OT_M;
pos = POS_BELOW_C;
}
/* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil,
* so the Indic shaper needs to know their categories. */
else if (unlikely (u == 0x11303u)) cat = OT_SM;
else if (unlikely (u == 0x1133cu)) cat = OT_N;
else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/behdad/harfbuzz/issues/552 */
else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/behdad/harfbuzz/issues/538 */
else if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */
else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u)))
cat = OT_PLACEHOLDER;
@ -677,6 +691,21 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
hb_glyph_info_t *info = buffer->info;
/* https://github.com/behdad/harfbuzz/issues/435#issuecomment-335560167
* // For compatibility with legacy useage in Kannada,
* // Ra+h+ZWJ must behave like Ra+ZWJ+h...
*/
if (buffer->props.script == HB_SCRIPT_KANNADA &&
start + 3 <= end &&
is_one_of (info[start ], FLAG (OT_Ra)) &&
is_one_of (info[start+1], FLAG (OT_H)) &&
is_one_of (info[start+2], FLAG (OT_ZWJ)))
{
buffer->merge_clusters (start+1, start+3);
hb_glyph_info_t tmp = info[start+1];
info[start+1] = info[start+2];
info[start+2] = tmp;
}
/* 1. Find base consonant:
*
@ -842,8 +871,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* 2. Decompose and reorder Matras:
*
* Each matra and any syllable modifier sign in the cluster are moved to the
* appropriate position relative to the consonant(s) in the cluster. The
* Each matra and any syllable modifier sign in the syllable are moved to the
* appropriate position relative to the consonant(s) in the syllable. The
* shaping engine decomposes two- or three-part matras into their constituent
* parts before any repositioning. Matra characters are classified by which
* consonant in a conjunct they have affinity for and are reordered to the
@ -1269,7 +1298,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
/* This function relies heavily on halant glyphs. Lots of ligation
* and possibly multiplication substitutions happened prior to this
* and possibly multiple substitutions happened prior to this
* phase, and that might have messed up our properties. Recover
* from a particular case of that where we're fairly sure that a
* class of OT_H is desired but has been lost. */
@ -1293,7 +1322,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* After the localized forms and basic shaping forms GSUB features have been
* applied (see below), the shaping engine performs some final glyph
* reordering before applying all the remaining font features to the entire
* cluster.
* syllable.
*/
bool try_pref = !!indic_plan->mask_array[PREF];
@ -1676,8 +1705,8 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
break;
default:
/* Uniscribe merges the entire cluster... Except for Tamil & Sinhala.
* This means, half forms are submerged into the main consonants cluster.
/* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala.
* This means, half forms are submerged into the main consonant's cluster.
* This is unnecessary, and makes cursor positioning harder, but that's what
* Uniscribe does. */
buffer->merge_clusters (start, end);
@ -1826,6 +1855,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
compose_indic,
setup_masks_indic,
NULL, /* disable_otl */
NULL, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};

View File

@ -34,197 +34,201 @@
#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u,
5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 30u, 3u, 29u, 1u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 8u, 8u, 0
3u, 30u, 3u, 29u, 1u, 32u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 32u, 8u, 8u, 0
};
static const char _myanmar_syllable_machine_key_spans[] = {
31, 28, 25, 4, 25, 23, 21, 21,
32, 28, 25, 4, 25, 23, 21, 21,
27, 27, 27, 27, 16, 27, 27, 27,
27, 27, 27, 27, 27, 27, 25, 4,
25, 23, 21, 21, 27, 27, 27, 27,
28, 27, 30, 27, 27, 27, 27, 27,
27, 27, 27, 27, 1
28, 27, 32, 27, 27, 27, 27, 27,
27, 27, 27, 27, 32, 1
};
static const short _myanmar_syllable_machine_index_offsets[] = {
0, 32, 61, 87, 92, 118, 142, 164,
186, 214, 242, 270, 298, 315, 343, 371,
399, 427, 455, 483, 511, 539, 567, 593,
598, 624, 648, 670, 692, 720, 748, 776,
804, 833, 861, 892, 920, 948, 976, 1004,
1032, 1060, 1088, 1116, 1144
0, 33, 62, 88, 93, 119, 143, 165,
187, 215, 243, 271, 299, 316, 344, 372,
400, 428, 456, 484, 512, 540, 568, 594,
599, 625, 649, 671, 693, 721, 749, 777,
805, 834, 862, 895, 923, 951, 979, 1007,
1035, 1063, 1091, 1119, 1147, 1180
};
static const char _myanmar_syllable_machine_indicies[] = {
1, 1, 2, 3, 4, 4, 0, 5,
0, 6, 1, 0, 0, 0, 0, 7,
0, 8, 1, 0, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 0,
21, 22, 23, 23, 20, 24, 20, 25,
20, 20, 20, 20, 20, 20, 20, 26,
20, 20, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 20, 23, 23, 20,
24, 20, 20, 20, 20, 20, 20, 20,
20, 20, 37, 20, 20, 20, 20, 20,
20, 31, 20, 20, 20, 35, 20, 23,
23, 20, 24, 20, 23, 23, 20, 24,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
31, 20, 20, 20, 35, 20, 38, 20,
23, 23, 20, 24, 20, 31, 20, 20,
20, 20, 20, 20, 20, 39, 20, 20,
20, 20, 20, 20, 31, 20, 23, 23,
20, 24, 20, 20, 20, 20, 20, 20,
20, 20, 20, 39, 20, 20, 20, 20,
20, 20, 31, 20, 23, 23, 20, 24,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
31, 20, 21, 20, 23, 23, 20, 24,
20, 25, 20, 20, 20, 20, 20, 20,
20, 40, 20, 20, 40, 20, 20, 20,
31, 41, 20, 20, 35, 20, 21, 20,
23, 23, 20, 24, 20, 25, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 31, 20, 20, 20,
35, 20, 21, 20, 23, 23, 20, 24,
20, 25, 20, 20, 20, 20, 20, 20,
20, 40, 20, 20, 20, 20, 20, 20,
31, 41, 20, 20, 35, 20, 21, 20,
23, 23, 20, 24, 20, 25, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 31, 41, 20, 20,
35, 20, 1, 1, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 1, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 26, 20, 20, 27, 28, 29,
30, 31, 32, 33, 34, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 34, 20,
20, 20, 20, 20, 20, 31, 32, 33,
34, 35, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 31, 32, 33, 34, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 31, 32, 33,
20, 35, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 31, 20, 33, 20, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 34, 20,
20, 27, 20, 29, 20, 31, 32, 33,
34, 35, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 34, 20, 20, 27, 20, 20,
20, 31, 32, 33, 34, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 34, 20,
20, 27, 28, 29, 20, 31, 32, 33,
34, 35, 20, 21, 22, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 26, 20, 20, 27, 28, 29,
30, 31, 32, 33, 34, 35, 20, 3,
3, 42, 5, 42, 42, 42, 42, 42,
42, 42, 42, 42, 43, 42, 42, 42,
42, 42, 42, 13, 42, 42, 42, 17,
42, 3, 3, 42, 5, 42, 3, 3,
42, 5, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 42, 42, 42, 17, 42,
44, 42, 3, 3, 42, 5, 42, 13,
42, 42, 42, 42, 42, 42, 42, 45,
42, 42, 42, 42, 42, 42, 13, 42,
3, 3, 42, 5, 42, 42, 42, 42,
42, 42, 42, 42, 42, 45, 42, 42,
42, 42, 42, 42, 13, 42, 3, 3,
42, 5, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 46, 42, 42, 46, 42,
42, 42, 13, 47, 42, 42, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 13, 42,
42, 42, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 46, 42, 42, 42, 42,
42, 42, 13, 47, 42, 42, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 13, 47,
42, 42, 17, 42, 21, 22, 23, 23,
20, 24, 20, 25, 20, 20, 20, 20,
20, 20, 20, 48, 20, 20, 27, 28,
0, 8, 9, 0, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 1,
0, 22, 23, 24, 24, 21, 25, 21,
26, 21, 21, 21, 21, 21, 21, 21,
27, 21, 21, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 21, 24, 24,
21, 25, 21, 21, 21, 21, 21, 21,
21, 21, 21, 38, 21, 21, 21, 21,
21, 21, 32, 21, 21, 21, 36, 21,
24, 24, 21, 25, 21, 24, 24, 21,
25, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 32, 21, 21, 21, 36, 21, 39,
21, 24, 24, 21, 25, 21, 32, 21,
21, 21, 21, 21, 21, 21, 40, 21,
21, 21, 21, 21, 21, 32, 21, 24,
24, 21, 25, 21, 21, 21, 21, 21,
21, 21, 21, 21, 40, 21, 21, 21,
21, 21, 21, 32, 21, 24, 24, 21,
25, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 32, 21, 22, 21, 24, 24, 21,
25, 21, 26, 21, 21, 21, 21, 21,
21, 21, 41, 21, 21, 41, 21, 21,
21, 32, 42, 21, 21, 36, 21, 22,
21, 24, 24, 21, 25, 21, 26, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 32, 21, 21,
21, 36, 21, 22, 21, 24, 24, 21,
25, 21, 26, 21, 21, 21, 21, 21,
21, 21, 41, 21, 21, 21, 21, 21,
21, 32, 42, 21, 21, 36, 21, 22,
21, 24, 24, 21, 25, 21, 26, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 32, 42, 21,
21, 36, 21, 1, 1, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 1, 21, 22, 21, 24, 24,
21, 25, 21, 26, 21, 21, 21, 21,
21, 21, 21, 27, 21, 21, 28, 29,
30, 31, 32, 33, 34, 35, 36, 21,
22, 21, 24, 24, 21, 25, 21, 26,
21, 21, 21, 21, 21, 21, 21, 35,
21, 21, 21, 21, 21, 21, 32, 33,
34, 35, 36, 21, 22, 21, 24, 24,
21, 25, 21, 26, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 32, 33, 34, 35, 36, 21,
22, 21, 24, 24, 21, 25, 21, 26,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 32, 33,
34, 21, 36, 21, 22, 21, 24, 24,
21, 25, 21, 26, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 32, 21, 34, 21, 36, 21,
22, 21, 24, 24, 21, 25, 21, 26,
21, 21, 21, 21, 21, 21, 21, 35,
21, 21, 28, 21, 30, 21, 32, 33,
34, 35, 36, 21, 22, 21, 24, 24,
21, 25, 21, 26, 21, 21, 21, 21,
21, 21, 21, 35, 21, 21, 28, 21,
21, 21, 32, 33, 34, 35, 36, 21,
22, 21, 24, 24, 21, 25, 21, 26,
21, 21, 21, 21, 21, 21, 21, 35,
21, 21, 28, 29, 30, 21, 32, 33,
34, 35, 36, 21, 22, 23, 24, 24,
21, 25, 21, 26, 21, 21, 21, 21,
21, 21, 21, 27, 21, 21, 28, 29,
30, 31, 32, 33, 34, 35, 36, 21,
3, 3, 43, 5, 43, 43, 43, 43,
43, 43, 43, 43, 43, 44, 43, 43,
43, 43, 43, 43, 14, 43, 43, 43,
18, 43, 3, 3, 43, 5, 43, 3,
3, 43, 5, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 14, 43, 43, 43, 18,
43, 45, 43, 3, 3, 43, 5, 43,
14, 43, 43, 43, 43, 43, 43, 43,
46, 43, 43, 43, 43, 43, 43, 14,
43, 3, 3, 43, 5, 43, 43, 43,
43, 43, 43, 43, 43, 43, 46, 43,
43, 43, 43, 43, 43, 14, 43, 3,
3, 43, 5, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 14, 43, 2, 43, 3,
3, 43, 5, 43, 6, 43, 43, 43,
43, 43, 43, 43, 47, 43, 43, 47,
43, 43, 43, 14, 48, 43, 43, 18,
43, 2, 43, 3, 3, 43, 5, 43,
6, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 14,
43, 43, 43, 18, 43, 2, 43, 3,
3, 43, 5, 43, 6, 43, 43, 43,
43, 43, 43, 43, 47, 43, 43, 43,
43, 43, 43, 14, 48, 43, 43, 18,
43, 2, 43, 3, 3, 43, 5, 43,
6, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 14,
48, 43, 43, 18, 43, 22, 23, 24,
24, 21, 25, 21, 26, 21, 21, 21,
21, 21, 21, 21, 49, 21, 21, 28,
29, 30, 31, 32, 33, 34, 35, 36,
20, 21, 49, 23, 23, 20, 24, 20,
25, 20, 20, 20, 20, 20, 20, 20,
26, 20, 20, 27, 28, 29, 30, 31,
32, 33, 34, 35, 20, 1, 1, 2,
3, 3, 3, 42, 5, 42, 6, 1,
42, 42, 42, 42, 1, 42, 8, 1,
42, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 8, 42, 42, 9, 10,
11, 12, 13, 14, 15, 16, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 16,
42, 42, 42, 42, 42, 42, 13, 14,
15, 16, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 14, 15, 16, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 13, 14,
15, 42, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 42, 15, 42, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 16,
42, 42, 9, 42, 11, 42, 13, 14,
15, 16, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 16, 42, 42, 9, 42,
42, 42, 13, 14, 15, 16, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 16,
42, 42, 9, 10, 11, 42, 13, 14,
15, 16, 17, 42, 2, 3, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 8, 42, 42, 9, 10,
11, 12, 13, 14, 15, 16, 17, 42,
51, 50, 0
37, 21, 22, 50, 24, 24, 21, 25,
21, 26, 21, 21, 21, 21, 21, 21,
21, 27, 21, 21, 28, 29, 30, 31,
32, 33, 34, 35, 36, 21, 1, 1,
2, 3, 3, 3, 43, 5, 43, 6,
1, 43, 43, 43, 43, 1, 43, 8,
43, 43, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 43, 1, 43, 2,
43, 3, 3, 43, 5, 43, 6, 43,
43, 43, 43, 43, 43, 43, 8, 43,
43, 10, 11, 12, 13, 14, 15, 16,
17, 18, 43, 2, 43, 3, 3, 43,
5, 43, 6, 43, 43, 43, 43, 43,
43, 43, 17, 43, 43, 43, 43, 43,
43, 14, 15, 16, 17, 18, 43, 2,
43, 3, 3, 43, 5, 43, 6, 43,
43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 14, 15, 16,
17, 18, 43, 2, 43, 3, 3, 43,
5, 43, 6, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43,
43, 14, 15, 16, 43, 18, 43, 2,
43, 3, 3, 43, 5, 43, 6, 43,
43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 14, 43, 16,
43, 18, 43, 2, 43, 3, 3, 43,
5, 43, 6, 43, 43, 43, 43, 43,
43, 43, 17, 43, 43, 10, 43, 12,
43, 14, 15, 16, 17, 18, 43, 2,
43, 3, 3, 43, 5, 43, 6, 43,
43, 43, 43, 43, 43, 43, 17, 43,
43, 10, 43, 43, 43, 14, 15, 16,
17, 18, 43, 2, 43, 3, 3, 43,
5, 43, 6, 43, 43, 43, 43, 43,
43, 43, 17, 43, 43, 10, 11, 12,
43, 14, 15, 16, 17, 18, 43, 2,
3, 3, 3, 43, 5, 43, 6, 43,
43, 43, 43, 43, 43, 43, 8, 43,
43, 10, 11, 12, 13, 14, 15, 16,
17, 18, 43, 1, 1, 51, 51, 51,
51, 51, 51, 51, 51, 1, 51, 51,
51, 51, 1, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 1, 51, 52, 51, 0
};
static const char _myanmar_syllable_machine_trans_targs[] = {
0, 1, 22, 0, 0, 23, 29, 32,
35, 36, 40, 41, 42, 25, 38, 39,
37, 28, 43, 44, 0, 2, 12, 0,
3, 9, 13, 14, 18, 19, 20, 5,
16, 17, 15, 8, 21, 4, 6, 7,
10, 11, 0, 24, 26, 27, 30, 31,
33, 34, 0, 0
35, 44, 36, 40, 41, 42, 25, 38,
39, 37, 28, 43, 45, 0, 2, 12,
0, 3, 9, 13, 14, 18, 19, 20,
5, 16, 17, 15, 8, 21, 4, 6,
7, 10, 11, 0, 24, 26, 27, 30,
31, 33, 34, 0, 0
};
static const char _myanmar_syllable_machine_trans_actions[] = {
3, 0, 0, 4, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 6, 0, 0, 7,
0, 0, 0, 0, 0, 6, 0, 0,
7, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 8, 0, 0, 0, 0, 0,
0, 0, 9, 10
0, 0, 0, 8, 0, 0, 0, 0,
0, 0, 0, 9, 10
};
static const char _myanmar_syllable_machine_to_state_actions[] = {
@ -233,7 +237,7 @@ static const char _myanmar_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0
};
static const char _myanmar_syllable_machine_from_state_actions[] = {
@ -242,16 +246,16 @@ static const char _myanmar_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0
};
static const short _myanmar_syllable_machine_eof_trans[] = {
0, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43,
21, 21, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 51
0, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
22, 22, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 52, 52
};
static const int myanmar_syllable_machine_start = 0;
@ -265,7 +269,7 @@ static const int myanmar_syllable_machine_en_main = 0;
#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
#define found_syllable(syllable_type) \
@ -285,7 +289,7 @@ find_syllables (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
#line 289 "hb-ot-shape-complex-myanmar-machine.hh"
#line 293 "hb-ot-shape-complex-myanmar-machine.hh"
{
cs = myanmar_syllable_machine_start;
ts = 0;
@ -293,7 +297,7 @@ find_syllables (hb_buffer_t *buffer)
act = 0;
}
#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
#line 115 "hb-ot-shape-complex-myanmar-machine.rl"
p = 0;
@ -302,7 +306,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int last = 0;
unsigned int syllable_serial = 1;
#line 306 "hb-ot-shape-complex-myanmar-machine.hh"
#line 310 "hb-ot-shape-complex-myanmar-machine.hh"
{
int _slen;
int _trans;
@ -316,7 +320,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
#line 320 "hb-ot-shape-complex-myanmar-machine.hh"
#line 324 "hb-ot-shape-complex-myanmar-machine.hh"
}
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@ -335,38 +339,38 @@ _eof_trans:
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
case 7:
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (consonant_syllable); }}
break;
case 5:
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 10:
#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (punctuation_cluster); }}
break;
case 4:
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 3:
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 6:
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
case 8:
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
case 9:
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
break;
#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
#line 374 "hb-ot-shape-complex-myanmar-machine.hh"
}
_again:
@ -375,7 +379,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
#line 379 "hb-ot-shape-complex-myanmar-machine.hh"
#line 383 "hb-ot-shape-complex-myanmar-machine.hh"
}
if ( ++p != pe )
@ -391,7 +395,7 @@ _again:
}
#line 123 "hb-ot-shape-complex-myanmar-machine.rl"
#line 124 "hb-ot-shape-complex-myanmar-machine.rl"
}

View File

@ -41,7 +41,7 @@
A = 10;
As = 18;
C = 1;
D = 19;
D = 32;
D0 = 20;
DB = 3;
GB = 11;
@ -62,6 +62,7 @@ ZWJ = 6;
ZWNJ = 5;
Ra = 16;
P = 31;
CS = 19;
j = ZWJ|ZWNJ; # Joiners
k = (Ra As H); # Kinzi
@ -76,7 +77,7 @@ pwo_tone_group = PT A* DB? As?;
complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?;
syllable_tail = (H | complex_syllable_tail);
consonant_syllable = k? (c|IV|D|GB).VS? (H (c|IV).VS?)* syllable_tail;
consonant_syllable = (k|CS)? (c|IV|D|GB).VS? (H (c|IV).VS?)* syllable_tail;
punctuation_cluster = P V;
broken_cluster = k? VS? syllable_tail;
other = any;

View File

@ -130,8 +130,7 @@ enum syllable_type_t {
/* Note: This enum is duplicated in the -machine.rl source file.
* Not sure how to avoid duplication. */
enum myanmar_category_t {
OT_As = 18, /* Asat */
OT_D = 19, /* Digits except zero */
OT_As = 18, /* Asat */
OT_D0 = 20, /* Digit zero */
OT_DB = OT_N, /* Dot below */
OT_GB = OT_PLACEHOLDER,
@ -145,7 +144,8 @@ enum myanmar_category_t {
OT_VPre = 28,
OT_VPst = 29,
OT_VS = 30, /* Variation selectors */
OT_P = 31 /* Punctuation */
OT_P = 31, /* Punctuation */
OT_D = 32, /* Digits except zero */
};
@ -524,6 +524,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old =
NULL, /* compose */
NULL, /* setup_masks */
NULL, /* disable_otl */
NULL, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
@ -542,6 +543,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
NULL, /* compose */
setup_masks_myanmar,
NULL, /* disable_otl */
NULL, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
false, /* fallback_position */
};

View File

@ -39,6 +39,8 @@
#define complex_var_u8_1() var2.u8[3]
#define HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS 32
enum hb_ot_shape_zero_width_marks_type_t {
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
@ -154,6 +156,16 @@ struct hb_ot_complex_shaper_t
*/
bool (*disable_otl) (const hb_ot_shape_plan_t *plan);
/* reorder_marks()
* Called during shape().
* Shapers can use to modify ordering of combining marks.
* May be NULL.
*/
void (*reorder_marks) (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
unsigned int start,
unsigned int end);
hb_ot_shape_zero_width_marks_type_t zero_width_marks;
bool fallback_position;
@ -253,10 +265,12 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_SINHALA:
/* If the designer designed the font for the 'DFLT' script,
* use the default shaper. Otherwise, use the specific shaper.
* (or we ended up arbitrarily pick 'latn'), use the default shaper.
* Otherwise, use the specific shaper.
* Note that for some simple scripts, there may not be *any*
* GSUB/GPOS needed, so there may be no scripts found! */
if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
planner->map.chosen_script[0] == HB_TAG ('l','a','t','n'))
return &_hb_ot_complex_shaper_default;
else
return &_hb_ot_complex_shaper_indic;
@ -362,11 +376,18 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_MARCHEN:
case HB_SCRIPT_NEWA:
/* Unicode-10.0 additions */
case HB_SCRIPT_MASARAM_GONDI:
case HB_SCRIPT_SOYOMBO:
case HB_SCRIPT_ZANABAZAR_SQUARE:
/* If the designer designed the font for the 'DFLT' script,
* use the default shaper. Otherwise, use the specific shaper.
* (or we ended up arbitrarily pick 'latn'), use the default shaper.
* Otherwise, use the specific shaper.
* Note that for some simple scripts, there may not be *any*
* GSUB/GPOS needed, so there may be no scripts found! */
if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
planner->map.chosen_script[0] == HB_TAG ('l','a','t','n'))
return &_hb_ot_complex_shaper_default;
else
return &_hb_ot_complex_shaper_use;

View File

@ -378,6 +378,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
NULL, /* compose */
NULL, /* setup_masks */
NULL, /* disable_otl */
NULL, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
false,/* fallback_position */
};

View File

@ -58,6 +58,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan =
NULL, /* compose */
NULL, /* setup_masks */
NULL, /* disable_otl */
NULL, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};

View File

@ -36,33 +36,33 @@
#line 38 "hb-ot-shape-complex-use-machine.hh"
static const unsigned char _use_syllable_machine_trans_keys[] = {
1u, 1u, 0u, 39u, 21u, 21u, 8u, 39u, 8u, 39u, 1u, 1u, 8u, 39u, 8u, 39u,
1u, 1u, 0u, 43u, 21u, 21u, 8u, 39u, 8u, 39u, 1u, 1u, 8u, 39u, 8u, 39u,
8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
13u, 21u, 4u, 4u, 13u, 13u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u,
8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 1u, 1u, 1u, 39u, 8u, 39u,
21u, 42u, 41u, 42u, 42u, 42u, 0
21u, 42u, 41u, 42u, 42u, 42u, 1u, 5u, 0
};
static const char _use_syllable_machine_key_spans[] = {
1, 40, 1, 32, 32, 1, 32, 32,
1, 44, 1, 32, 32, 1, 32, 32,
32, 19, 19, 19, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
9, 1, 1, 32, 32, 32, 32, 19,
19, 19, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 1, 39, 32,
22, 2, 1
22, 2, 1, 5
};
static const short _use_syllable_machine_index_offsets[] = {
0, 2, 43, 45, 78, 111, 113, 146,
179, 212, 232, 252, 272, 305, 338, 371,
404, 437, 470, 503, 536, 569, 602, 635,
668, 678, 680, 682, 715, 748, 781, 814,
834, 854, 874, 907, 940, 973, 1006, 1039,
1072, 1105, 1138, 1171, 1204, 1237, 1239, 1279,
1312, 1335, 1338
0, 2, 47, 49, 82, 115, 117, 150,
183, 216, 236, 256, 276, 309, 342, 375,
408, 441, 474, 507, 540, 573, 606, 639,
672, 682, 684, 686, 719, 752, 785, 818,
838, 858, 878, 911, 944, 977, 1010, 1043,
1076, 1109, 1142, 1175, 1208, 1241, 1243, 1283,
1316, 1339, 1342, 1344
};
static const char _use_syllable_machine_indicies[] = {
@ -71,191 +71,192 @@ static const char _use_syllable_machine_indicies[] = {
4, 4, 2, 2, 8, 9, 4, 4,
10, 11, 12, 13, 14, 15, 16, 10,
17, 18, 19, 20, 21, 22, 4, 23,
24, 25, 4, 27, 26, 29, 28, 28,
30, 31, 28, 28, 28, 28, 28, 28,
28, 28, 32, 33, 34, 35, 36, 37,
38, 39, 33, 40, 32, 41, 42, 43,
44, 28, 45, 46, 47, 28, 29, 28,
28, 30, 31, 28, 28, 28, 28, 28,
28, 28, 28, 48, 33, 34, 35, 36,
37, 38, 39, 33, 40, 41, 41, 42,
43, 44, 28, 45, 46, 47, 28, 30,
49, 29, 28, 28, 30, 31, 28, 28,
28, 28, 28, 28, 28, 28, 28, 33,
34, 35, 36, 37, 38, 39, 33, 40,
41, 41, 42, 43, 44, 28, 45, 46,
47, 28, 29, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
33, 34, 35, 36, 37, 28, 28, 28,
28, 28, 28, 42, 43, 44, 28, 45,
46, 47, 28, 29, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 34, 35, 36, 37, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
45, 46, 47, 28, 29, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 35, 36, 37, 28,
29, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
28, 36, 37, 28, 29, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 37, 28,
29, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
35, 36, 37, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 45, 46, 47,
28, 29, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
28, 35, 36, 37, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 46,
47, 28, 29, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 35, 36, 37, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
28, 47, 28, 29, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 34, 35, 36, 37, 28, 28,
28, 28, 28, 28, 42, 43, 44, 28,
45, 46, 47, 28, 29, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 34, 35, 36, 37, 28,
28, 28, 28, 28, 28, 28, 43, 44,
28, 45, 46, 47, 28, 29, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 34, 35, 36, 37,
28, 28, 28, 28, 28, 28, 28, 28,
44, 28, 45, 46, 47, 28, 29, 28,
28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 33, 34, 35, 36,
37, 28, 39, 33, 28, 28, 28, 42,
43, 44, 28, 45, 46, 47, 28, 29,
28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 33, 34, 35,
36, 37, 28, 50, 33, 28, 28, 28,
42, 43, 44, 28, 45, 46, 47, 28,
29, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 33, 34,
35, 36, 37, 28, 28, 33, 28, 28,
28, 42, 43, 44, 28, 45, 46, 47,
28, 29, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 33,
34, 35, 36, 37, 38, 39, 33, 28,
28, 28, 42, 43, 44, 28, 45, 46,
47, 28, 29, 28, 28, 30, 31, 28,
28, 28, 28, 28, 28, 28, 28, 28,
33, 34, 35, 36, 37, 38, 39, 33,
40, 28, 41, 42, 43, 44, 28, 45,
46, 47, 28, 29, 28, 28, 30, 31,
28, 28, 28, 28, 28, 28, 28, 28,
28, 33, 34, 35, 36, 37, 38, 39,
33, 40, 32, 41, 42, 43, 44, 28,
45, 46, 47, 28, 52, 51, 51, 51,
51, 51, 51, 51, 53, 51, 5, 54,
52, 51, 6, 55, 55, 1, 56, 55,
55, 55, 55, 55, 55, 55, 55, 57,
24, 25, 4, 4, 4, 26, 4, 28,
27, 30, 29, 29, 31, 32, 29, 29,
29, 29, 29, 29, 29, 29, 33, 34,
35, 36, 37, 38, 39, 40, 34, 41,
33, 42, 43, 44, 45, 29, 46, 47,
48, 29, 30, 29, 29, 31, 32, 29,
29, 29, 29, 29, 29, 29, 29, 49,
34, 35, 36, 37, 38, 39, 40, 34,
41, 42, 42, 43, 44, 45, 29, 46,
47, 48, 29, 31, 50, 30, 29, 29,
31, 32, 29, 29, 29, 29, 29, 29,
29, 29, 29, 34, 35, 36, 37, 38,
39, 40, 34, 41, 42, 42, 43, 44,
45, 29, 46, 47, 48, 29, 30, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 34, 35, 36, 37,
38, 29, 29, 29, 29, 29, 29, 43,
44, 45, 29, 46, 47, 48, 29, 30,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 35, 36,
37, 38, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 46, 47, 48, 29,
30, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
36, 37, 38, 29, 30, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 37, 38, 29,
30, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 38, 29, 30, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 36, 37, 38, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 46, 47, 48, 29, 30, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 36, 37, 38,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 47, 48, 29, 30, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 36, 37,
38, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 48, 29, 30,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 35, 36,
37, 38, 29, 29, 29, 29, 29, 29,
43, 44, 45, 29, 46, 47, 48, 29,
30, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 35,
36, 37, 38, 29, 29, 29, 29, 29,
29, 29, 44, 45, 29, 46, 47, 48,
29, 30, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
35, 36, 37, 38, 29, 29, 29, 29,
29, 29, 29, 29, 45, 29, 46, 47,
48, 29, 30, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
34, 35, 36, 37, 38, 29, 40, 34,
29, 29, 29, 43, 44, 45, 29, 46,
47, 48, 29, 30, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 34, 35, 36, 37, 38, 29, 51,
34, 29, 29, 29, 43, 44, 45, 29,
46, 47, 48, 29, 30, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 34, 35, 36, 37, 38, 29,
29, 34, 29, 29, 29, 43, 44, 45,
29, 46, 47, 48, 29, 30, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 34, 35, 36, 37, 38,
39, 40, 34, 29, 29, 29, 43, 44,
45, 29, 46, 47, 48, 29, 30, 29,
29, 31, 32, 29, 29, 29, 29, 29,
29, 29, 29, 29, 34, 35, 36, 37,
38, 39, 40, 34, 41, 29, 42, 43,
44, 45, 29, 46, 47, 48, 29, 30,
29, 29, 31, 32, 29, 29, 29, 29,
29, 29, 29, 29, 29, 34, 35, 36,
37, 38, 39, 40, 34, 41, 33, 42,
43, 44, 45, 29, 46, 47, 48, 29,
53, 52, 52, 52, 52, 52, 52, 52,
54, 52, 5, 55, 53, 52, 6, 56,
56, 1, 57, 56, 56, 56, 56, 56,
56, 56, 56, 58, 10, 11, 12, 13,
14, 15, 16, 10, 17, 19, 19, 20,
21, 22, 56, 23, 24, 25, 56, 6,
56, 56, 1, 57, 56, 56, 56, 56,
56, 56, 56, 56, 56, 10, 11, 12,
13, 14, 15, 16, 10, 17, 19, 19,
20, 21, 22, 56, 23, 24, 25, 56,
6, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 10, 11,
12, 13, 14, 56, 56, 56, 56, 56,
56, 20, 21, 22, 56, 23, 24, 25,
56, 6, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
11, 12, 13, 14, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 23, 24,
25, 56, 6, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 12, 13, 14, 56, 6, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 13,
14, 56, 6, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 14, 56, 6, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 12, 13,
14, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 23, 24, 25, 56, 6,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 12,
13, 14, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 24, 25, 56,
6, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
12, 13, 14, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 25,
56, 6, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
11, 12, 13, 14, 56, 56, 56, 56,
56, 56, 20, 21, 22, 56, 23, 24,
25, 56, 6, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 11, 12, 13, 14, 56, 56, 56,
56, 56, 56, 56, 21, 22, 56, 23,
24, 25, 56, 6, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 11, 12, 13, 14, 56, 56,
56, 56, 56, 56, 56, 56, 22, 56,
23, 24, 25, 56, 6, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 10, 11, 12, 13, 14, 56,
16, 10, 56, 56, 56, 20, 21, 22,
56, 23, 24, 25, 56, 6, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 10, 11, 12, 13, 14,
56, 59, 10, 56, 56, 56, 20, 21,
22, 56, 23, 24, 25, 56, 6, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 10, 11, 12, 13,
14, 56, 56, 10, 56, 56, 56, 20,
21, 22, 56, 23, 24, 25, 56, 6,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 10, 11, 12,
13, 14, 15, 16, 10, 56, 56, 56,
20, 21, 22, 56, 23, 24, 25, 56,
6, 56, 56, 1, 57, 56, 56, 56,
56, 56, 56, 56, 56, 56, 10, 11,
12, 13, 14, 15, 16, 10, 17, 56,
19, 20, 21, 22, 56, 23, 24, 25,
56, 1, 60, 3, 56, 56, 56, 3,
56, 56, 6, 56, 56, 1, 57, 56,
56, 56, 56, 56, 56, 56, 56, 56,
10, 11, 12, 13, 14, 15, 16, 10,
17, 19, 19, 20, 21, 22, 55, 23,
24, 25, 55, 6, 55, 55, 1, 56,
55, 55, 55, 55, 55, 55, 55, 55,
55, 10, 11, 12, 13, 14, 15, 16,
10, 17, 19, 19, 20, 21, 22, 55,
23, 24, 25, 55, 6, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 10, 11, 12, 13, 14, 55,
55, 55, 55, 55, 55, 20, 21, 22,
55, 23, 24, 25, 55, 6, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 11, 12, 13, 14,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 23, 24, 25, 55, 6, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 12, 13,
14, 55, 6, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 13, 14, 55, 6, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
14, 55, 6, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 12, 13, 14, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 23,
24, 25, 55, 6, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 12, 13, 14, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 24, 25, 55, 6, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 12, 13, 14, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 25, 55, 6, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 11, 12, 13, 14,
55, 55, 55, 55, 55, 55, 20, 21,
22, 55, 23, 24, 25, 55, 6, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 11, 12, 13,
14, 55, 55, 55, 55, 55, 55, 55,
21, 22, 55, 23, 24, 25, 55, 6,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 11, 12,
13, 14, 55, 55, 55, 55, 55, 55,
55, 55, 22, 55, 23, 24, 25, 55,
6, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 10, 11,
12, 13, 14, 55, 16, 10, 55, 55,
55, 20, 21, 22, 55, 23, 24, 25,
55, 6, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 10,
11, 12, 13, 14, 55, 58, 10, 55,
55, 55, 20, 21, 22, 55, 23, 24,
25, 55, 6, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
10, 11, 12, 13, 14, 55, 55, 10,
55, 55, 55, 20, 21, 22, 55, 23,
24, 25, 55, 6, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 10, 11, 12, 13, 14, 15, 16,
10, 55, 55, 55, 20, 21, 22, 55,
23, 24, 25, 55, 6, 55, 55, 1,
56, 55, 55, 55, 55, 55, 55, 55,
55, 55, 10, 11, 12, 13, 14, 15,
16, 10, 17, 55, 19, 20, 21, 22,
55, 23, 24, 25, 55, 1, 59, 3,
55, 55, 55, 3, 55, 55, 6, 55,
55, 1, 56, 55, 55, 55, 55, 55,
55, 55, 55, 55, 10, 11, 12, 13,
14, 15, 16, 10, 17, 18, 19, 20,
21, 22, 55, 23, 24, 25, 55, 6,
55, 55, 1, 56, 55, 55, 55, 55,
55, 55, 55, 55, 55, 10, 11, 12,
13, 14, 15, 16, 10, 17, 18, 19,
20, 21, 22, 55, 23, 24, 25, 55,
61, 60, 60, 60, 60, 60, 60, 60,
60, 60, 60, 60, 60, 60, 60, 60,
60, 60, 60, 60, 61, 62, 60, 61,
62, 60, 62, 60, 0
17, 18, 19, 20, 21, 22, 56, 23,
24, 25, 56, 6, 56, 56, 1, 57,
56, 56, 56, 56, 56, 56, 56, 56,
56, 10, 11, 12, 13, 14, 15, 16,
10, 17, 18, 19, 20, 21, 22, 56,
23, 24, 25, 56, 62, 61, 61, 61,
61, 61, 61, 61, 61, 61, 61, 61,
61, 61, 61, 61, 61, 61, 61, 61,
62, 63, 61, 62, 63, 61, 63, 61,
3, 60, 60, 60, 3, 60, 0
};
static const char _use_syllable_machine_trans_targs[] = {
1, 27, 2, 3, 1, 24, 1, 45,
46, 48, 29, 30, 31, 32, 33, 40,
41, 43, 47, 44, 37, 38, 39, 34,
35, 36, 1, 1, 1, 1, 4, 5,
23, 7, 8, 9, 10, 11, 18, 19,
21, 22, 15, 16, 17, 12, 13, 14,
6, 1, 20, 1, 25, 26, 1, 1,
0, 28, 42, 1, 1, 49, 50
35, 36, 51, 1, 1, 1, 1, 4,
5, 23, 7, 8, 9, 10, 11, 18,
19, 21, 22, 15, 16, 17, 12, 13,
14, 6, 1, 20, 1, 25, 26, 1,
1, 0, 28, 42, 1, 1, 49, 50
};
static const char _use_syllable_machine_trans_actions[] = {
1, 2, 0, 0, 5, 0, 6, 0,
2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 2, 2, 0, 0, 0, 0,
0, 0, 7, 8, 9, 10, 0, 0,
0, 0, 0, 7, 8, 9, 10, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 11, 0, 12, 0, 0, 13, 14,
0, 2, 0, 15, 16, 0, 0
0, 0, 11, 0, 12, 0, 0, 13,
14, 0, 2, 0, 15, 16, 0, 0
};
static const char _use_syllable_machine_to_state_actions[] = {
@ -265,7 +266,7 @@ static const char _use_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0
0, 0, 0, 0
};
static const char _use_syllable_machine_from_state_actions[] = {
@ -275,17 +276,17 @@ static const char _use_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0
0, 0, 0, 0
};
static const short _use_syllable_machine_eof_trans[] = {
1, 0, 27, 29, 29, 50, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
52, 55, 52, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 60, 56, 56,
61, 61, 61
1, 0, 28, 30, 30, 51, 30, 30,
30, 30, 30, 30, 30, 30, 30, 30,
30, 30, 30, 30, 30, 30, 30, 30,
53, 56, 53, 57, 57, 57, 57, 57,
57, 57, 57, 57, 57, 57, 57, 57,
57, 57, 57, 57, 57, 61, 57, 57,
62, 62, 62, 61
};
static const int use_syllable_machine_start = 1;
@ -299,7 +300,7 @@ static const int use_syllable_machine_en_main = 1;
#line 139 "hb-ot-shape-complex-use-machine.rl"
#line 140 "hb-ot-shape-complex-use-machine.rl"
#define found_syllable(syllable_type) \
@ -319,7 +320,7 @@ find_syllables (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
#line 323 "hb-ot-shape-complex-use-machine.hh"
#line 324 "hb-ot-shape-complex-use-machine.hh"
{
cs = use_syllable_machine_start;
ts = 0;
@ -327,7 +328,7 @@ find_syllables (hb_buffer_t *buffer)
act = 0;
}
#line 160 "hb-ot-shape-complex-use-machine.rl"
#line 161 "hb-ot-shape-complex-use-machine.rl"
p = 0;
@ -336,7 +337,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int last = 0;
unsigned int syllable_serial = 1;
#line 340 "hb-ot-shape-complex-use-machine.hh"
#line 341 "hb-ot-shape-complex-use-machine.hh"
{
int _slen;
int _trans;
@ -350,7 +351,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
#line 354 "hb-ot-shape-complex-use-machine.hh"
#line 355 "hb-ot-shape-complex-use-machine.hh"
}
_keys = _use_syllable_machine_trans_keys + (cs<<1);
@ -373,58 +374,58 @@ _eof_trans:
{te = p+1;}
break;
case 8:
#line 128 "hb-ot-shape-complex-use-machine.rl"
#line 129 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (independent_cluster); }}
break;
case 10:
#line 130 "hb-ot-shape-complex-use-machine.rl"
#line 131 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (standard_cluster); }}
break;
case 6:
#line 134 "hb-ot-shape-complex-use-machine.rl"
#line 135 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 5:
#line 135 "hb-ot-shape-complex-use-machine.rl"
#line 136 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (non_cluster); }}
break;
case 7:
#line 128 "hb-ot-shape-complex-use-machine.rl"
#line 129 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (independent_cluster); }}
break;
case 11:
#line 129 "hb-ot-shape-complex-use-machine.rl"
#line 130 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (virama_terminated_cluster); }}
break;
case 9:
#line 130 "hb-ot-shape-complex-use-machine.rl"
#line 131 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (standard_cluster); }}
break;
case 13:
#line 131 "hb-ot-shape-complex-use-machine.rl"
#line 132 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }}
break;
case 12:
#line 132 "hb-ot-shape-complex-use-machine.rl"
#line 133 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (numeral_cluster); }}
break;
case 16:
#line 133 "hb-ot-shape-complex-use-machine.rl"
#line 134 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (symbol_cluster); }}
break;
case 14:
#line 134 "hb-ot-shape-complex-use-machine.rl"
#line 135 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
case 15:
#line 135 "hb-ot-shape-complex-use-machine.rl"
#line 136 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (non_cluster); }}
break;
case 1:
#line 134 "hb-ot-shape-complex-use-machine.rl"
#line 135 "hb-ot-shape-complex-use-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
break;
#line 428 "hb-ot-shape-complex-use-machine.hh"
#line 429 "hb-ot-shape-complex-use-machine.hh"
}
_again:
@ -433,7 +434,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
#line 437 "hb-ot-shape-complex-use-machine.hh"
#line 438 "hb-ot-shape-complex-use-machine.hh"
}
if ( ++p != pe )
@ -449,7 +450,7 @@ _again:
}
#line 169 "hb-ot-shape-complex-use-machine.rl"
#line 170 "hb-ot-shape-complex-use-machine.rl"
}

View File

@ -86,6 +86,7 @@ VMPst = 39; # VOWEL_MOD_POST
VMPre = 23; # VOWEL_MOD_PRE
SMAbv = 41; # SYM_MOD_ABOVE
SMBlw = 42; # SYM_MOD_BELOW
CS = 43; # CONS_WITH_STACKER
consonant_modifiers = CMAbv* CMBlw* ((H B | SUB) VS? CMAbv? CMBlw*)*;
@ -96,12 +97,12 @@ vowel_modifiers = VMPre* VMAbv* VMBlw* VMPst*;
final_consonants = FAbv* FBlw* FPst* FM?;
virama_terminated_cluster =
R? (B | GB) VS?
(R|CS)? (B | GB) VS?
consonant_modifiers
H
;
standard_cluster =
R? (B | GB) VS?
(R|CS)? (B | GB) VS?
consonant_modifiers
medial_consonants
dependent_vowels

View File

@ -87,7 +87,8 @@ enum use_category_t {
USE_VMPst = 39, /* VOWEL_MOD_POST */
USE_VMPre = 23, /* VOWEL_MOD_PRE */
USE_SMAbv = 41, /* SYM_MOD_ABOVE */
USE_SMBlw = 42 /* SYM_MOD_BELOW */
USE_SMBlw = 42, /* SYM_MOD_BELOW */
USE_CS = 43 /* CONS_WITH_STACKER */
};
HB_INTERNAL USE_TABLE_ELEMENT_TYPE

View File

@ -6,12 +6,12 @@
*
* on files with these headers:
*
* # IndicSyllabicCategory-9.0.0.txt
* # Date: 2016-05-21, 02:46:00 GMT [RP]
* # IndicPositionalCategory-9.0.0.txt
* # Date: 2016-06-09, 19:33:00 GMT [RP]
* # Blocks-9.0.0.txt
* # Date: 2016-02-05, 23:48:00 GMT [KW]
* # IndicSyllabicCategory-10.0.0.txt
* # Date: 2017-05-31, 01:07:00 GMT [KW, RP]
* # IndicPositionalCategory-10.0.0.txt
* # Date: 2017-05-31, 01:07:00 GMT [RP]
* # Blocks-10.0.0.txt
* # Date: 2017-04-12, 17:30:00 GMT [KW]
* UnicodeData.txt does not have a header.
*/
@ -19,6 +19,7 @@
#define B USE_B /* BASE */
#define CGJ USE_CGJ /* CGJ */
#define CS USE_CS /* CONS_WITH_STACKER */
#define FM USE_FM /* CONS_FINAL_MOD */
#define GB USE_GB /* BASE_OTHER */
#define H USE_H /* HALANT */
@ -97,7 +98,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, IND, O,
/* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B,
/* 09E0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
/* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, O, O,
/* Gurmukhi */
@ -119,7 +120,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0AC0 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, O, VAbv, VAbv, VAbv, O, VPst, VPst, H, O, O,
/* 0AD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 0AE0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0AF0 */ O, O, O, O, O, O, O, O, O, B, O, O, O, O, O, O,
/* 0AF0 */ O, O, O, O, O, O, O, O, O, B, VMAbv, VMAbv, VMAbv, CMAbv, CMAbv, CMAbv,
/* Oriya */
@ -163,14 +164,14 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0CC0 */ VAbv, VPst, VPst, VPst, VPst, O, VAbv, VAbv, VAbv, O, VAbv, VAbv, VAbv, H, O, O,
/* 0CD0 */ O, O, O, O, O, VPst, VPst, O, O, O, O, O, O, O, B, O,
/* 0CE0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0CF0 */ O, R, R, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 0CF0 */ O, CS, CS, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Malayalam */
/* 0D00 */ O, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, B, B,
/* 0D00 */ VMAbv, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, B, B,
/* 0D10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, O, O, B, VPst, VPst,
/* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, VAbv, VAbv, B, VPst, VPst,
/* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O,
/* 0D50 */ O, O, O, O, IND, IND, IND, VPst, O, O, O, O, O, O, O, B,
/* 0D60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
@ -274,9 +275,9 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1A30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1A50 */ B, B, B, B, B, MPre, MBlw, FPst, FAbv, FAbv, FAbv, FBlw, FBlw, FBlw, FBlw, O,
/* 1A50 */ B, B, B, B, B, MPre, MBlw, SUB, FAbv, FAbv, FAbv, SUB, SUB, SUB, SUB, O,
/* 1A60 */ H, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre,
/* 1A70 */ VPre, VPre, VPre, VAbv, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, FM, FM, FM, O, O, FM,
/* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, FM, FM, O, O, FBlw,
/* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
/* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
@ -323,7 +324,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw,
/* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O,
/* 1CF0 */ O, O, VMPst, VMPst, VMAbv, O, O, O, VMAbv, VMAbv, O, O, O, O, O, O,
/* 1CF0 */ O, O, VMPst, VMPst, VMAbv, O, O, VMPst, VMAbv, VMAbv, O, O, O, O, O, O,
#define use_offset_0x1df8u 2552
@ -376,7 +377,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* Devanagari Extended */
/* A8E0 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,
/* A8F0 */ VMAbv, VMAbv, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* A8F0 */ VMAbv, VMAbv, B, B, O, O, O, O, O, O, O, O, O, O, O, O,
/* Kayah Li */
@ -397,7 +398,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* A980 */ VMAbv, VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B,
/* A990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* A9A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, SUB, MPst, MPst,
/* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, SUB, MPst, MBlw,
/* A9C0 */ H, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* A9D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
@ -467,7 +468,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* Brahmi */
/* 11000 */ VMPst, VMAbv, VMPst, R, R, B, B, B, B, B, B, B, B, B, B, B,
/* 11000 */ VMPst, VMAbv, VMPst, CS, CS, B, B, B, B, B, B, B, B, B, B, B,
/* 11010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11030 */ B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw,
@ -545,7 +546,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
/* 11330 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VPst,
/* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O,
/* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O,
/* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, B, B,
/* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
/* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
@ -615,7 +616,26 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O,
/* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O,
#define use_offset_0x11c00u 4960
#define use_offset_0x11a00u 4960
/* Zanabazar Square */
/* 11A00 */ B, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VAbv, VAbv, VBlw, B, B, B, B, B,
/* 11A10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11A30 */ B, B, B, FM, VBlw, VMAbv, VMAbv, VMAbv, VMAbv, VMPst, R, MBlw, MBlw, MBlw, MBlw, GB,
/* 11A40 */ O, O, O, O, O, GB, O, H, O, O, O, O, O, O, O, O,
/* Soyombo */
/* 11A50 */ B, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VBlw, VBlw, VBlw, B, B, B, B,
/* 11A60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11A70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11A80 */ B, B, B, B, O, O, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw,
/* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, O, O, O,
#define use_offset_0x11c00u 5120
/* Bhaiksuki */
@ -636,7 +656,19 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O,
}; /* Table items: 5144; occupancy: 72% */
#define use_offset_0x11d00u 5304
/* Masaram Gondi */
/* 11D00 */ B, B, B, B, B, B, B, O, B, B, O, B, B, B, B, B,
/* 11D10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11D30 */ B, VAbv, VAbv, VAbv, VAbv, VAbv, VBlw, O, O, O, VAbv, O, VAbv, VAbv, O, VAbv,
/* 11D40 */ VMAbv, VMAbv, CMBlw, VAbv, VBlw, H, R, MBlw, O, O, O, O, O, O, O, O,
/* 11D50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
}; /* Table items: 5400; occupancy: 73% */
USE_TABLE_ELEMENT_TYPE
hb_use_get_categories (hb_codepoint_t u)
@ -684,7 +716,9 @@ hb_use_get_categories (hb_codepoint_t u)
if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u];
if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u];
if (hb_in_range<hb_codepoint_t> (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u];
if (hb_in_range<hb_codepoint_t> (u, 0x11A00u, 0x11A9Fu)) return use_table[u - 0x11A00u + use_offset_0x11a00u];
if (hb_in_range<hb_codepoint_t> (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u];
if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11D5Fu)) return use_table[u - 0x11D00u + use_offset_0x11d00u];
if (unlikely (u == 0x1107Fu)) return HN;
break;
@ -696,6 +730,7 @@ hb_use_get_categories (hb_codepoint_t u)
#undef B
#undef CGJ
#undef CS
#undef FM
#undef GB
#undef H

View File

@ -607,6 +607,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use =
compose_use,
setup_masks_use,
NULL, /* disable_otl */
NULL, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
false, /* fallback_position */
};

View File

@ -345,14 +345,18 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
break;
/* We are going to do a O(n^2). Only do this if the sequence is short. */
if (end - i > 10) {
/* We are going to do a O(n^2). Only do this if the sequence is short,
* but not too short ;). */
if (end - i < 2 || end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
i = end;
continue;
}
buffer->sort (i, end, compare_combining_class);
if (plan->shaper->reorder_marks)
plan->shaper->reorder_marks (plan, buffer, i, end);
i = end;
}
@ -369,46 +373,58 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
buffer->clear_output ();
count = buffer->len;
unsigned int starter = 0;
bool combine = true;
buffer->next_glyph ();
while (buffer->idx < count && !buffer->in_error)
{
hb_codepoint_t composed, glyph;
if (/* We don't try to compose a non-mark character with it's preceding starter.
if (combine &&
/* We don't try to compose a non-mark character with it's preceding starter.
* This is both an optimization to avoid trying to compose every two neighboring
* glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul
* fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())) &&
/* If there's anything between the starter and this char, they should have CCC
* smaller than this character's. */
(starter == buffer->out_len - 1 ||
_hb_glyph_info_get_modified_combining_class (&buffer->prev()) < _hb_glyph_info_get_modified_combining_class (&buffer->cur())) &&
/* And compose. */
c.compose (&c,
buffer->out_info[starter].codepoint,
buffer->cur().codepoint,
&composed) &&
/* And the font has glyph for the composite. */
font->get_nominal_glyph (composed, &glyph))
HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())))
{
/* Composes. */
buffer->next_glyph (); /* Copy to out-buffer. */
if (unlikely (buffer->in_error))
return;
buffer->merge_out_clusters (starter, buffer->out_len);
buffer->out_len--; /* Remove the second composable. */
/* Modify starter and carry on. */
buffer->out_info[starter].codepoint = composed;
buffer->out_info[starter].glyph_index() = glyph;
_hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
if (/* If there's anything between the starter and this char, they should have CCC
* smaller than this character's. */
(starter == buffer->out_len - 1 ||
info_cc (buffer->prev()) < info_cc (buffer->cur())) &&
/* And compose. */
c.compose (&c,
buffer->out_info[starter].codepoint,
buffer->cur().codepoint,
&composed) &&
/* And the font has glyph for the composite. */
font->get_nominal_glyph (composed, &glyph))
{
/* Composes. */
buffer->next_glyph (); /* Copy to out-buffer. */
if (unlikely (buffer->in_error))
return;
buffer->merge_out_clusters (starter, buffer->out_len);
buffer->out_len--; /* Remove the second composable. */
/* Modify starter and carry on. */
buffer->out_info[starter].codepoint = composed;
buffer->out_info[starter].glyph_index() = glyph;
_hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
continue;
continue;
}
else if (/* We sometimes custom-tailor the sorted order of marks. In that case, stop
* trying to combine as soon as combining-class drops. */
starter < buffer->out_len - 1 &&
info_cc (buffer->prev()) > info_cc (buffer->cur()))
combine = false;
}
/* Blocked, or doesn't compose. */
buffer->next_glyph ();
if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
if (info_cc (buffer->prev()) == 0)
{
starter = buffer->out_len - 1;
combine = true;
}
}
buffer->swap_buffers ();

View File

@ -693,9 +693,9 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
static inline void
hb_ot_position_complex (hb_ot_shape_context_t *c)
{
hb_ot_layout_position_start (c->font, c->buffer);
unsigned int count = c->buffer->len;
hb_glyph_info_t *info = c->buffer->info;
hb_glyph_position_t *pos = c->buffer->pos;
/* If the font has no GPOS, AND, no fallback positioning will
* happen, AND, direction is forward, then when zeroing mark
@ -710,6 +710,17 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
!c->plan->shaper->fallback_position &&
HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
/* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
/* The nil glyph_h_origin() func returns 0, so no need to apply it. */
if (c->font->has_glyph_h_origin_func ())
for (unsigned int i = 0; i < count; i++)
c->font->add_glyph_h_origin (info[i].codepoint,
&pos[i].x_offset,
&pos[i].y_offset);
hb_ot_layout_position_start (c->font, c->buffer);
switch (c->plan->shaper->zero_width_marks)
{
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
@ -723,30 +734,8 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
}
if (likely (!c->fallback_positioning))
{
hb_glyph_info_t *info = c->buffer->info;
hb_glyph_position_t *pos = c->buffer->pos;
/* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
/* The nil glyph_h_origin() func returns 0, so no need to apply it. */
if (c->font->has_glyph_h_origin_func ())
for (unsigned int i = 0; i < count; i++)
c->font->add_glyph_h_origin (info[i].codepoint,
&pos[i].x_offset,
&pos[i].y_offset);
c->plan->position (c->font, c->buffer);
/* The nil glyph_h_origin() func returns 0, so no need to apply it. */
if (c->font->has_glyph_h_origin_func ())
for (unsigned int i = 0; i < count; i++)
c->font->subtract_glyph_h_origin (info[i].codepoint,
&pos[i].x_offset,
&pos[i].y_offset);
}
switch (c->plan->shaper->zero_width_marks)
{
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
@ -763,6 +752,13 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
hb_ot_layout_position_finish_advances (c->font, c->buffer);
hb_ot_zero_width_default_ignorables (c);
hb_ot_layout_position_finish_offsets (c->font, c->buffer);
/* The nil glyph_h_origin() func returns 0, so no need to apply it. */
if (c->font->has_glyph_h_origin_func ())
for (unsigned int i = 0; i < count; i++)
c->font->subtract_glyph_h_origin (info[i].codepoint,
&pos[i].x_offset,
&pos[i].y_offset);
}
static inline void

View File

@ -270,28 +270,36 @@ static const LangTag ot_languages[] = {
{"cak", HB_TAG('C','A','K',' ')}, /* Kaqchikel */
{"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano */
{"cbl", HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin */
{"cco", HB_TAG('C','C','H','N')}, /* Chinantec */
{"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
{"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */
{"cfm", HB_TAG('H','A','L',' ')}, /* Halam/Falam Chin */
{"cgg", HB_TAG('C','G','G',' ')}, /* Chiga */
{"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */
{"chj", HB_TAG('C','C','H','N')}, /* Chinantec */
{"chk", HB_TAG('C','H','K','0')}, /* Chuukese */
{"cho", HB_TAG('C','H','O',' ')}, /* Choctaw */
{"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
{"chq", HB_TAG('C','C','H','N')}, /* Chinantec */
{"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */
{"chy", HB_TAG('C','H','Y',' ')}, /* Cheyenne */
{"chz", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cja", HB_TAG('C','J','A',' ')}, /* Western Cham */
{"cjm", HB_TAG('C','J','M',' ')}, /* Eastern Cham */
{"cka", HB_TAG('Q','I','N',' ')}, /* Khumi Awa Chin */
{"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish (Sorani) */
{"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */
{"cld", HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic */
{"cle", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cmr", HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin */
{"cnb", HB_TAG('Q','I','N',' ')}, /* Chinbon Chin */
{"cnh", HB_TAG('Q','I','N',' ')}, /* Hakha Chin */
{"cnk", HB_TAG('Q','I','N',' ')}, /* Khumi Chin */
{"cnl", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cnt", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cnw", HB_TAG('Q','I','N',' ')}, /* Ngawn Chin */
{"cop", HB_TAG('C','O','P',' ')}, /* Coptic */
{"cpa", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cpp", HB_TAG('C','P','P',' ')}, /* Creoles */
{"cr", HB_TAG('C','R','E',' ')}, /* Cree */
{"cre", HB_TAG('Y','C','R',' ')}, /* Y-Cree */
@ -302,15 +310,21 @@ static const LangTag ot_languages[] = {
{"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
{"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
{"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
{"csa", HB_TAG('C','C','H','N')}, /* Chinantec */
{"csb", HB_TAG('C','S','B',' ')}, /* Kashubian */
{"csh", HB_TAG('Q','I','N',' ')}, /* Asho Chin */
{"cso", HB_TAG('C','C','H','N')}, /* Chinantec */
{"csy", HB_TAG('Q','I','N',' ')}, /* Siyin Chin */
{"ctd", HB_TAG('Q','I','N',' ')}, /* Tedim Chin */
{"cte", HB_TAG('C','C','H','N')}, /* Chinantec */
{"ctg", HB_TAG('C','T','G',' ')}, /* Chittagonian */
{"ctl", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol */
{"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */
{"cuc", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cuk", HB_TAG('C','U','K',' ')}, /* San Blas Kuna */
{"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */
{"cvn", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */
{"cy", HB_TAG('W','E','L',' ')}, /* Welsh */
{"czt", HB_TAG('Q','I','N',' ')}, /* Zotung Chin */
@ -380,7 +394,6 @@ static const LangTag ot_languages[] = {
{"gkp", HB_TAG('G','K','P',' ')}, /* Kpelle (Guinea) */
{"gl", HB_TAG('G','A','L',' ')}, /* Galician */
{"gld", HB_TAG('N','A','N',' ')}, /* Nanai */
{"gle", HB_TAG('I','R','T',' ')}, /* Irish Traditional */
{"glk", HB_TAG('G','L','K',' ')}, /* Gilaki */
{"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */
{"gnn", HB_TAG('G','N','N',' ')}, /* Gumatj */
@ -538,7 +551,6 @@ static const LangTag ot_languages[] = {
{"mag", HB_TAG('M','A','G',' ')}, /* Magahi */
{"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
{"mak", HB_TAG('M','K','R',' ')}, /* Makasar */
{"mal", HB_TAG('M','A','L',' ')}, /* Malayalam */
{"mam", HB_TAG('M','A','M',' ')}, /* Mam */
{"man", HB_TAG('M','N','K',' ')}, /* Manding/Mandingo [macrolanguage] */
{"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */

View File

@ -88,11 +88,23 @@ struct hb_shaper_data_t {
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data);
#define HB_SHAPER_DATA_ENSURE_DEFINE(shaper, object) \
HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, true)
#define HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, condition) \
bool \
HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
{\
retry: \
HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \
if (likely (data) && !(condition)) { \
/* Drop and recreate. */ \
/* If someone dropped it in the mean time, throw it away and don't touch it. \
* Otherwise, destruct it. */ \
if (hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), data, NULL)) { \
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
} \
goto retry; \
} \
if (unlikely (!data)) { \
data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \
if (unlikely (!data)) \

View File

@ -160,17 +160,23 @@ static const hb_script_t ucdn_script_translate[] =
HB_SCRIPT_NEWA,
HB_SCRIPT_OSAGE,
HB_SCRIPT_TANGUT,
HB_SCRIPT_MASARAM_GONDI,
HB_SCRIPT_NUSHU,
HB_SCRIPT_SOYOMBO,
HB_SCRIPT_ZANABAZAR_SQUARE,
};
static hb_unicode_combining_class_t
hb_ucdn_combining_class(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
hb_ucdn_combining_class(hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t unicode,
void *user_data HB_UNUSED)
{
return (hb_unicode_combining_class_t) ucdn_get_combining_class(unicode);
}
static unsigned int
hb_ucdn_eastasian_width(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
hb_ucdn_eastasian_width(hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t unicode,
void *user_data HB_UNUSED)
{
int w = ucdn_get_east_asian_width(unicode);
@ -178,28 +184,31 @@ hb_ucdn_eastasian_width(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
}
static hb_unicode_general_category_t
hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t unicode,
void *user_data HB_UNUSED)
{
return (hb_unicode_general_category_t)ucdn_get_general_category(unicode);
}
static hb_codepoint_t
hb_ucdn_mirroring(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
hb_ucdn_mirroring(hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t unicode,
void *user_data HB_UNUSED)
{
return ucdn_mirror(unicode);
}
static hb_script_t
hb_ucdn_script(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
hb_ucdn_script(hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t unicode,
void *user_data HB_UNUSED)
{
return ucdn_script_translate[ucdn_get_script(unicode)];
}
static hb_bool_t
hb_ucdn_compose(hb_unicode_funcs_t *ufuncs,
hb_ucdn_compose(hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab,
void *user_data HB_UNUSED)
{
@ -207,7 +216,7 @@ hb_ucdn_compose(hb_unicode_funcs_t *ufuncs,
}
static hb_bool_t
hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs,
hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b,
void *user_data HB_UNUSED)
{
@ -215,7 +224,7 @@ hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs,
}
static unsigned int
hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs,
hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t u, hb_codepoint_t *decomposed,
void *user_data HB_UNUSED)
{

View File

@ -105,14 +105,10 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
inline unsigned int
modified_combining_class (hb_codepoint_t unicode)
{
/* XXX This hack belongs to the Arabic shaper:
* Put HAMZA ABOVE in the same class as SHADDA. */
if (unlikely (unicode == 0x0654u)) unicode = 0x0651u;
/* XXX This hack belongs to the Myanmar shaper. */
if (unlikely (unicode == 0x1037u)) unicode = 0x103Au;
/* XXX This hack belongs to the SEA shaper (for Tai Tham):
/* XXX This hack belongs to the USE shaper (for Tai Tham):
* Reorder SAKOT to ensure it comes after any tone marks. */
if (unlikely (unicode == 0x1A60u)) return 254;
@ -141,6 +137,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
* we do NOT want to hide them, as the way Uniscribe has implemented them
* is with regular spacing glyphs, and that's the way fonts are made to work.
* As such, we make exceptions for those four.
* Also ignoring U+1BCA0..1BCA3. https://github.com/behdad/harfbuzz/issues/503
*
* Unicode 7.0:
* $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/'
@ -197,8 +194,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
{
/* Other planes */
switch (plane) {
case 0x01: return hb_in_ranges<hb_codepoint_t> (ch, 0x1BCA0u, 0x1BCA3u,
0x1D173u, 0x1D17Au);
case 0x01: return hb_in_range<hb_codepoint_t> (ch, 0x1D173u, 0x1D17Au);
case 0x0E: return hb_in_range<hb_codepoint_t> (ch, 0xE0000u, 0xE0FFFu);
default: return false;
}

View File

@ -37,10 +37,10 @@ HB_BEGIN_DECLS
#define HB_VERSION_MAJOR 1
#define HB_VERSION_MINOR 5
#define HB_VERSION_MICRO 1
#define HB_VERSION_MINOR 6
#define HB_VERSION_MICRO 0
#define HB_VERSION_STRING "1.5.1"
#define HB_VERSION_STRING "1.6.0"
#define HB_VERSION_ATLEAST(major,minor,micro) \
((major)*10000+(minor)*100+(micro) <= \

View File

@ -1617,9 +1617,15 @@ public:
private:
#define GLYPH_BUFFER_SIZE (2048/sizeof(Glyph))
Glyph* GlyphBuffer()
{
return *mGlyphBuffer.addr();
}
Glyph *AppendGlyph()
{
return &mGlyphBuffer[mNumGlyphs++];
return &GlyphBuffer()[mNumGlyphs++];
}
static DrawMode
@ -1640,13 +1646,13 @@ private:
}
if (mRunParams.isRTL) {
Glyph *begin = &mGlyphBuffer[0];
Glyph *end = &mGlyphBuffer[mNumGlyphs];
Glyph *begin = &GlyphBuffer()[0];
Glyph *end = &GlyphBuffer()[mNumGlyphs];
std::reverse(begin, end);
}
gfx::GlyphBuffer buf;
buf.mGlyphs = mGlyphBuffer;
buf.mGlyphs = GlyphBuffer();
buf.mNumGlyphs = mNumGlyphs;
const gfxContext::AzureState &state = mRunParams.context->CurrentState();
@ -1788,7 +1794,9 @@ private:
mFontParams.renderingOptions);
}
Glyph mGlyphBuffer[GLYPH_BUFFER_SIZE];
// Allocate space for a buffer of Glyph records, without initializing them.
AlignedStorage2<Glyph[GLYPH_BUFFER_SIZE]> mGlyphBuffer;
unsigned int mNumGlyphs;
#undef GLYPH_BUFFER_SIZE

View File

@ -1,14 +0,0 @@
# 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 $(topsrcdir)/config/rules.mk
ifndef MOZ_EXCLUDE_HYPHENATION_DICTIONARIES
PATTERN_FILES = $(strip $(wildcard $(srcdir)/*/hyphenation/*.dic))
ifneq (,$(PATTERN_FILES))
libs::
$(INSTALL) $(PATTERN_FILES) $(FINAL_TARGET)/hyphenation
endif
endif # MOZ_EXCLUDE_HYPHENATION_DICTIONARIES

View File

@ -4,3 +4,45 @@
# 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/.
locales = [
'af',
'bg',
'ca',
'cy',
'da',
'de-1901',
'de-1996',
'de-CH',
# 'en-US', # en-US is renamed -- see below.
'eo',
'es',
'et',
'fi',
'fr',
'gl',
'hr',
'hsb',
'hu',
'ia',
'is',
'it',
'kmr',
'la',
'lt',
'mn',
'nb',
'nl',
'nn',
'pl',
'pt',
'ru',
'sh',
'sl',
'sv',
'tr',
'uk',
]
filename = '{locale}/hyphenation/hyph_{locale}.dic'
FINAL_TARGET_FILES.hyphenation += [filename.format(locale=locale) for locale in locales]
# en-US is a special case: the dic file is named like en_US.
FINAL_TARGET_FILES.hyphenation += ['en-US/hyphenation/hyph_en_US.dic']

View File

@ -254,3 +254,15 @@ with only_when('--enable-compile-environment'):
set_config('LIBFUZZER', enable_libfuzzer)
set_define('LIBFUZZER', enable_libfuzzer)
# Enable pipeline operator
# ===================================================
js_option('--enable-pipeline-operator', default=False, help='Enable pipeline operator')
@depends('--enable-pipeline-operator')
def enable_pipeline_operator(value):
if value:
return True
set_config('ENABLE_PIPELINE_OPERATOR', enable_pipeline_operator)
set_define('ENABLE_PIPELINE_OPERATOR', enable_pipeline_operator)

Some files were not shown because too many files have changed in this diff Show More